diff --git a/.eslintignore b/.eslintignore deleted file mode 100644 index 59db356ed6..0000000000 --- a/.eslintignore +++ /dev/null @@ -1,4 +0,0 @@ -!.eslintrc.js -**/node_modules/** -**/VendorLib/** -**/flow-typed/** diff --git a/.eslintrc.js b/.eslintrc.js deleted file mode 100644 index 72eee21f89..0000000000 --- a/.eslintrc.js +++ /dev/null @@ -1,417 +0,0 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the license found in the LICENSE file in - * the root directory of this source tree. - * - * @noflow - */ -'use strict'; - -/* eslint comma-dangle: [1, always-multiline], prefer-object-spread/prefer-object-spread: 0 */ -/* eslint-disable max-len */ - -module.exports = { - root: true, - - parser: 'babel-eslint', - - parserOptions: { - ecmaVersion: 7, - sourceType: 'module', - ecmaFeatures: { - globalReturn: true, - jsx: true, - experimentalObjectRestSpread: true, - }, - }, - - // https://github.com/sindresorhus/globals/blob/master/globals.json - env: { - atomtest: true, - es6: true, - jasmine: true, - node: true, - }, - - globals: { - atom: false, - document: false, - window: false, - }, - - rules: { - // Possible Errors (http://eslint.org/docs/rules/#possible-errors) - 'no-await-in-loop': 1, - 'no-cond-assign': 1, - 'no-console': 1, - 'no-constant-condition': [1, {checkLoops: false}], - 'no-control-regex': 1, - 'no-debugger': 1, - 'no-dupe-args': 1, - 'no-dupe-keys': 1, - 'no-duplicate-case': 1, - 'no-empty-character-class': 1, - 'no-empty': [1, {allowEmptyCatch: true}], - 'no-ex-assign': 1, - 'no-extra-boolean-cast': 1, - 'no-extra-parens': 0, - 'no-extra-semi': 1, - 'no-func-assign': 1, - 'no-inner-declarations': 1, - 'no-invalid-regexp': 1, - 'no-irregular-whitespace': 1, - 'no-obj-calls': 1, - 'no-prototype-builtins': 0, - 'no-regex-spaces': 1, - 'no-sparse-arrays': 1, - 'no-template-curly-in-string': 0, - 'no-unexpected-multiline': 1, - 'no-unreachable': 1, - 'no-unsafe-finally': 1, - 'no-unsafe-negation': 1, - 'use-isnan': 1, - 'valid-jsdoc': 0, - 'valid-typeof': 1, - - // Best Practices (http://eslint.org/docs/rules/#best-practices) - 'accessor-pairs': 1, - 'array-callback-return': 0, - 'block-scoped-var': 0, - 'class-methods-use-this': 0, - 'complexity': 0, - 'consistent-return': 0, - 'curly': 1, - 'default-case': 0, - 'dot-location': [1, 'property'], - 'dot-notation': 1, - 'eqeqeq': [1, 'allow-null'], - 'guard-for-in': 0, - 'no-alert': 1, - 'no-caller': 1, - 'no-case-declarations': 0, - 'no-div-regex': 1, - 'no-else-return': 0, - 'no-empty-function': 0, - 'no-empty-pattern': 1, - 'no-eq-null': 0, - 'no-eval': 1, - 'no-extend-native': 1, - 'no-extra-bind': 1, - 'no-extra-label': 1, - 'no-fallthrough': 1, - 'no-floating-decimal': 1, - 'no-global-assign': 1, - 'no-implicit-coercion': 1, - 'no-implicit-globals': 0, - 'no-implied-eval': 1, - 'no-invalid-this': 0, - 'no-iterator': 1, - 'no-labels': 1, - 'no-lone-blocks': 1, - 'no-loop-func': 0, - 'no-magic-numbers': 0, - 'no-multi-spaces': 1, - 'no-multi-str': 0, - 'no-new-func': 1, - 'no-new-wrappers': 1, - 'no-new': 1, - 'no-octal-escape': 1, - 'no-octal': 1, - 'no-param-reassign': 1, - 'no-proto': 1, - 'no-redeclare': [1, {builtinGlobals: true}], - 'no-restricted-properties': 0, - 'no-return-assign': 1, - 'no-return-await': 1, - 'no-script-url': 1, - 'no-self-assign': 1, - 'no-self-compare': 1, - 'no-sequences': 1, - 'no-throw-literal': 1, - 'no-unmodified-loop-condition': 0, - 'no-unused-expressions': 0, - 'no-unused-labels': 1, - 'no-useless-call': 1, - 'no-useless-concat': 1, - 'no-useless-escape': 1, - 'no-useless-return': 0, - 'no-void': 1, - 'no-warning-comments': 0, - 'no-with': 1, - 'radix': 1, - 'require-await': 0, - // 'require-await': 1, - 'vars-on-top': 0, - 'wrap-iife': [1, 'inside'], - 'yoda': 1, - - // Strict Mode (http://eslint.org/docs/rules/#strict-mode) - 'strict': 0, - - // Variables (http://eslint.org/docs/rules/#variables) - 'init-declarations': 0, - 'no-catch-shadow': 1, - 'no-delete-var': 1, - 'no-label-var': 1, - 'no-restricted-globals': 0, - 'no-shadow-restricted-names': 1, - 'no-shadow': 1, - 'no-undef-init': 0, - 'no-undef': 1, - 'no-undefined': 0, - 'no-unused-vars': [1, {args: 'none'}], - 'no-use-before-define': 0, - - // Node.js and CommonJS (http://eslint.org/docs/rules/#nodejs-and-commonjs) - 'callback-return': 0, - 'global-require': 0, - 'handle-callback-err': 1, - 'no-mixed-requires': 1, - 'no-new-require': 1, - 'no-path-concat': 1, - 'no-process-env': 0, - 'no-process-exit': 0, - 'no-restricted-modules': 0, - 'no-sync': 0, - - // Stylistic Issues (http://eslint.org/docs/rules/#stylistic-issues) - 'array-bracket-spacing': 1, - 'block-spacing': 1, - 'brace-style': [1, '1tbs', {allowSingleLine: true}], - 'camelcase': 0, - 'capitalized-comments': 0, - 'comma-dangle': [1, {arrays: 'always-multiline', objects: 'always-multiline', imports: 'always-multiline', exports: 'always-multiline', functions: 'always-multiline'}], - 'comma-spacing': 1, - 'comma-style': 1, - 'computed-property-spacing': 1, - 'consistent-this': 0, - 'eol-last': 1, - 'func-call-spacing': 1, - 'func-name-matching': 0, - 'func-names': 0, - 'func-style': 0, - 'id-blacklist': 0, - 'id-length': 0, - 'id-match': 0, - 'indent': [1, 2, {SwitchCase: 1}], - 'jsx-quotes': [1, 'prefer-double'], - 'key-spacing': [1, {beforeColon: false, afterColon: true}], - 'keyword-spacing': 1, - 'line-comment-position': 0, - 'linebreak-style': 1, - 'lines-around-comment': 0, - 'lines-around-directive': 0, - 'max-depth': 0, - 'max-len': [1, 100, {tabWidth: 2, ignoreUrls: true}], - 'max-lines': 0, - 'max-nested-callbacks': 0, - 'max-params': 0, - 'max-statements-per-line': 0, - 'max-statements': 0, - 'multiline-ternary': 0, - 'new-cap': 0, - 'new-parens': 1, - 'newline-after-var': 0, - 'newline-before-return': 0, - 'newline-per-chained-call': 0, - 'no-array-constructor': 1, - 'no-bitwise': 1, - 'no-continue': 0, - 'no-inline-comments': 0, - 'no-lonely-if': 0, - 'no-mixed-operators': 0, - 'no-mixed-spaces-and-tabs': 1, - 'no-multiple-empty-lines': [1, {max: 2, maxBOF: 0, maxEOF: 1}], - 'no-negated-condition': 0, - 'no-nested-ternary': 0, - 'no-new-object': 1, - 'no-plusplus': 0, - 'no-restricted-syntax': 0, - 'no-tabs': 1, - 'no-ternary': 0, - 'no-trailing-spaces': 1, - 'no-underscore-dangle': 0, - 'no-unneeded-ternary': 0, - 'no-whitespace-before-property': 1, - 'object-curly-newline': 0, - 'object-curly-spacing': 1, - 'object-property-newline': 0, - 'one-var-declaration-per-line': 0, - 'one-var': [1, 'never'], - 'operator-assignment': 1, - 'operator-linebreak': 0, - 'padded-blocks': [1, {blocks: 'never', classes: 'never', switches: 'never'}], - 'quote-props': [1, 'consistent-as-needed'], - 'quotes': [1, 'single', 'avoid-escape'], - 'require-jsdoc': 0, - 'semi-spacing': 1, - 'semi': 1, - 'sort-keys': 0, - 'sort-vars': 0, - 'space-before-blocks': 1, - 'space-before-function-paren': [1, {anonymous: 'never', named: 'never', asyncArrow: 'always'}], - 'space-in-parens': [1, 'never'], - 'space-infix-ops': 1, - 'space-unary-ops': 1, - 'spaced-comment': [1, 'always', {line: {exceptions: ['-']}, block: {balanced: true}}], - 'unicode-bom': [1, 'never'], - 'wrap-regex': 0, - - // ECMAScript 6 (http://eslint.org/docs/rules/#ecmascript-6) - 'arrow-body-style': 0, - 'arrow-parens': [1, 'as-needed'], - 'arrow-spacing': 1, - 'constructor-super': 1, - 'generator-star-spacing': 1, - 'no-class-assign': 1, - 'no-confusing-arrow': [1, {allowParens: true}], - 'no-const-assign': 1, - 'no-dupe-class-members': 1, - 'no-duplicate-imports': 0, - 'no-new-symbol': 1, - 'no-restricted-imports': 0, - 'no-this-before-super': 1, - 'no-useless-computed-key': 1, - 'no-useless-constructor': 0, - 'no-useless-rename': 1, - 'no-var': 1, - 'object-shorthand': 1, - 'prefer-arrow-callback': [1, {allowNamedFunctions: true}], - 'prefer-const': 1, - 'prefer-numeric-literals': 0, - 'prefer-rest-params': 0, - 'prefer-spread': 1, - 'prefer-template': 0, - 'require-yield': 0, - 'rest-spread-spacing': 1, - 'sort-imports': 0, - 'symbol-description': 1, - 'template-curly-spacing': 1, - 'yield-star-spacing': 1, - - // dependencies (https://github.com/zertosh/eslint-plugin-dependencies) - 'dependencies/case-sensitive': 1, - 'dependencies/no-cycles': [0, {skip: ['/spec/', '/sample-[^/]+/']}], - 'dependencies/no-unresolved': 0, - 'dependencies/require-json-ext': 1, - - // flowtype (https://github.com/gajus/eslint-plugin-flowtype) - 'flowtype/boolean-style': 1, - 'flowtype/define-flow-type': 1, - 'flowtype/delimiter-dangle': [1, 'always-multiline'], - 'flowtype/generic-spacing': 1, - 'flowtype/no-dupe-keys': 0, - 'flowtype/no-primitive-constructor-types': 1, - 'flowtype/no-weak-types': 0, - 'flowtype/object-type-delimiter': 1, - 'flowtype/require-parameter-type': 0, - 'flowtype/require-return-type': 0, - 'flowtype/require-valid-file-annotation': 0, - 'flowtype/require-variable-type': 0, - 'flowtype/semi': 1, - 'flowtype/sort-keys': 0, - 'flowtype/space-after-type-colon': [1, 'always', {allowLineBreak: true}], - 'flowtype/space-before-generic-bracket': 1, - 'flowtype/space-before-type-colon': 1, - 'flowtype/type-id-match': 0, - 'flowtype/union-intersection-spacing': 1, - 'flowtype/use-flow-type': 1, - 'flowtype/valid-syntax': 0, - - // Jasmine (https://github.com/tlvince/eslint-plugin-jasmine) - 'jasmine/missing-expect': 0, - 'jasmine/named-spy': 0, - 'jasmine/no-assign-spyon': 0, - 'jasmine/no-disabled-tests': 1, - 'jasmine/no-expect-in-setup-teardown': 0, - 'jasmine/no-focused-tests': 0, - 'jasmine/no-global-setup': 0, - 'jasmine/no-spec-dupes': [1, 'branch'], - 'jasmine/no-suite-callback-args': 0, - 'jasmine/no-suite-dupes': [1, 'branch'], - 'jasmine/no-unsafe-spy': 0, - 'jasmine/valid-expect': 0, - - // nuclide-internal (https://github.com/facebook/nuclide/tree/master/resources/eslint-plugin-nuclide-internal) - 'nuclide-internal/atom-apis': 1, - 'nuclide-internal/consistent-import-name': 1, - 'nuclide-internal/import-type-style': 1, - 'nuclide-internal/license-header': 1, - 'nuclide-internal/no-cross-atom-imports': [1, {whitelist: ['nuclide-ui']}], - 'nuclide-internal/no-unnecessary-disposable-wrapping': 1, - 'nuclide-internal/prefer-nuclide-uri': 1, - - // prefer-object-spread (https://github.com/bryanrsmith/eslint-plugin-prefer-object-spread) - 'prefer-object-spread/prefer-object-spread': 1, - - // React (https://github.com/yannickcr/eslint-plugin-react) - 'react/display-name': 0, - 'react/forbid-component-props:': 0, - 'react/forbid-prop-types': 1, - 'react/no-array-index-key': 0, - 'react/no-children-prop': 0, - 'react/no-danger': 0, - 'react/no-danger-with-children': 0, - 'react/no-deprecated': 1, - 'react/no-did-mount-set-state': 0, - 'react/no-did-update-set-state': 0, - 'react/no-direct-mutation-state': 1, - 'react/no-find-dom-node': 0, - 'react/no-is-mounted': 0, - 'react/no-multi-comp': 0, - 'react/no-render-return-value': 0, - 'react/no-set-state': 0, - 'react/no-string-refs': 0, - 'react/no-unescaped-entities': 0, - 'react/no-unknown-property': 1, - 'react/no-unused-prop-types': 0, - 'react/prefer-es6-class': 0, - 'react/prefer-stateless-function': 0, - // 'react/prefer-stateless-function': 1, - 'react/prop-types': 1, - 'react/react-in-jsx-scope': 1, - 'react/require-default-props': 0, - 'react/require-optimization': 0, - 'react/require-render-return': 0, - 'react/self-closing-comp': 1, - 'react/sort-comp': 0, - 'react/sort-prop-types': 0, - 'react/style-prop-object': 0, - 'react/jsx-boolean-value': 0, - 'react/jsx-closing-bracket-location': [1, {selfClosing: 'tag-aligned', nonEmpty: 'after-props'}], - 'react/jsx-curly-spacing': [1, 'never'], - 'react/jsx-equals-spacing': 0, - 'react/jsx-filename-extension': 0, - 'react/jsx-first-prop-new-line': 0, - 'react/jsx-handler-names': 0, - 'react/jsx-indent': 0, - 'react/jsx-indent-props': 0, - 'react/jsx-key': 1, - 'react/jsx-max-props-per-line': 0, - 'react/jsx-no-bind': 0, - // 'react/jsx-no-bind': 1, - 'react/jsx-no-comment-textnodes': 0, - 'react/jsx-no-duplicate-props': 1, - 'react/jsx-no-literals': 0, - 'react/jsx-no-target-blank': 0, - 'react/jsx-no-undef': 1, - 'react/jsx-pascal-case': 0, - 'react/jsx-sort-props': 0, - 'react/jsx-space-before-closing': 1, - 'react/jsx-tag-spacing': 1, - 'react/jsx-uses-react': 1, - 'react/jsx-uses-vars': 1, - 'react/jxs-wrap-multilines': 0, - }, - - plugins: [ - 'dependencies', - 'flowtype', - 'jasmine', - 'nuclide-internal', - 'prefer-object-spread', - 'react', - ], -}; diff --git a/.flake8 b/.flake8 deleted file mode 100644 index 7da1f9608e..0000000000 --- a/.flake8 +++ /dev/null @@ -1,2 +0,0 @@ -[flake8] -max-line-length = 100 diff --git a/.flowconfig b/.flowconfig deleted file mode 100644 index 0458abfa9e..0000000000 --- a/.flowconfig +++ /dev/null @@ -1,34 +0,0 @@ -[include] - -[ignore] -; ignore module source to prefer declaration -/node_modules/classnames/.* -/node_modules/lru-cache/.* -/node_modules/react/.* -/node_modules/rxjs/.* -/node_modules/semver/.* -; annotated with `@flow` but have errors -/node_modules/fbjs/lib/.* -/pkg/nuclide-node-transpiler/spec/fixtures/.* -; large dirs that are not imported -/docs/.* -/pkg/nuclide-debugger/VendorLib/devtools/.* - -[libs] -flow-libs/ - -[options] -emoji=true -experimental.const_params=true -experimental.strict_type_args=true -module.use_strict=true -unsafe.enable_getters_and_setters=true - -suppress_comment=.*\\$FlowFixMe.* -suppress_comment=.*\\$FlowIssue.* -suppress_comment=.*\\$FlowIgnore.* -; uncommenting the next line will silence flow errors about missing 'fb' modules -; suppress_comment=.*\\$FlowFB.* - -[version] -0.38.0 diff --git a/.gitignore b/.gitignore index c04ae3d0c3..9a4f6630de 100644 --- a/.gitignore +++ b/.gitignore @@ -11,3 +11,35 @@ npm-debug.log* # Ignore locked gems because GitHub Pages controls the gems in production, # not Nuclide. Omit the lock so `bundle install` always installs the latest. /docs/Gemfile.lock + + +######################################################## +### !!!AUTO GENERATED by "prepare_apm_release.js"!!! ### +######################################################## + +# "apm" doesn't honor ".npmignore" files. As a workaround, we merge the +# ".npmignore" content into ".gitignore": +/.eslintignore +/.eslintrc.js +/.flake8 +/.flowconfig +/CONTRIBUTING.md +/ISSUE_TEMPLATE.md +/circle.yml +/docs +/flow-libs +/flow-typed +/pkg/sample-* +/resources/benchmarker +/resources/nuclicons +/scripts +spec + +# Ignore "BUCK" files, but not "buck/" directories. +# Note: These rules get inlined into ".gitignore" for apm publishing, git will +# ignore "buck/" directories without this exclusion on case-insensitive Macs. +BUCK +!buck/ + +/pkg/fb-java-rpc/**/*.java + diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md deleted file mode 100644 index 4d4a293802..0000000000 --- a/CONTRIBUTING.md +++ /dev/null @@ -1,48 +0,0 @@ -# Contributing to Nuclide -We want to make contributing to this project as easy and transparent as -possible. The -[Nuclide license](https://github.com/facebook/nuclide/blob/master/LICENSE) has -certain limitations around distribution. However, this does not affect your -ability to fork the project and make contributions. - -## Our Development Process -Nuclide is currently developed in Facebook's internal repositories and then -exported out to GitHub by a Facebook team member. We invite you to submit pull -requests directly to GitHub and, after review, these can be merged into the -project. - -## Pull Requests - -1. Fork the repo and create your branch from `master` for core changes, or -`gh-pages` for docs and website changes. -2. If you've added code that should be tested, add tests. -3. If you've changed APIs, update the documentation. -4. Ensure the test suite passes by running `scripts/test`. -5. Make sure your JavaScript code lints by using Flow. -6. If you haven't already, complete the Contributor License Agreement ("CLA"). - -## Contributor License Agreement ("CLA") -In order to accept your pull request, we need you to submit a CLA. You only need -to do this once to work on Nuclide and on Facebook's open source projects. - -Complete your CLA here: - -## Issues -We use GitHub issues to track public bugs. Please ensure your description is -clear and has sufficient instructions to be able to reproduce the issue. - -Facebook has a [bounty program](https://www.facebook.com/whitehat/) for the safe -disclosure of security bugs. In those cases, please go through the process -outlined on that page and do not file a public issue. - -## Coding Style -* Spaces for indentation rather than tabs - 2 for JavaScript, 4 for Python -* 100 character line length -* See the [project wiki](https://github.com/facebook/nuclide/wiki) for coding -practices and development tips. - -## License -By contributing to Nuclide, you agree that your contributions will be licensed -under the license outlined in the LICENSE file in the same directory as this -file. Due to certain limitations on distribution, this should not be considered -an [open source license](https://opensource.org/licenses/alphabetical). diff --git a/DEVELOPMENT b/DEVELOPMENT deleted file mode 100644 index 0c2e324251..0000000000 --- a/DEVELOPMENT +++ /dev/null @@ -1,3 +0,0 @@ -The existence of this file is used to denote that Nuclide is running from source. - -This file is *not* in `.npmignore` because the transpile script should delete it instead. diff --git a/ISSUE_TEMPLATE.md b/ISSUE_TEMPLATE.md deleted file mode 100644 index 0d1fbb5532..0000000000 --- a/ISSUE_TEMPLATE.md +++ /dev/null @@ -1,17 +0,0 @@ -### Issue and Steps to Reproduce -Describe your issue and tell us how to reproduce it (include screenshots and/or any console messages). - -### Expected Behavior -Tell us what should happen. - -### Actual Behavior -Tell us what happens instead. - -### Versions -* Atom: -* Nuclide: -* Client OS: -* Server OS (optional): - -### Additional Details -* Installed packages (`apm ls --installed`): diff --git a/circle.yml b/circle.yml deleted file mode 100644 index ce1fe88045..0000000000 --- a/circle.yml +++ /dev/null @@ -1,32 +0,0 @@ -machine: - node: - version: 6.5.0 - -test: - override: - # Do not run tests for releases. - - | - # eslint - if [[ "$CIRCLE_BRANCH" != "release-v"* ]]; then - ./node_modules/.bin/eslint --max-warnings=0 . - fi - - | - # flow - if [[ "$CIRCLE_BRANCH" != "release-v"* ]]; then - sed -i.tmp -e 's/^; \(suppress_comment=.*FlowFB.*\)$/\1/' .flowconfig - ./node_modules/.bin/flow check --show-all-errors - fi - -deployment: - release: - branch: /^release-v[0-9]+\.[0-9]+\.[0-9]+$/ - owner: facebook - commands: - - ./scripts/oss-publish.sh - -experimental: - notify: - branches: - only: - - master - - /^release-v[0-9]+\.[0-9]+\.[0-9]+$/ diff --git a/docs/CNAME b/docs/CNAME deleted file mode 100644 index 825146408a..0000000000 --- a/docs/CNAME +++ /dev/null @@ -1 +0,0 @@ -nuclide.io diff --git a/docs/CONTRIBUTING.md b/docs/CONTRIBUTING.md deleted file mode 100644 index 4e94e28fe2..0000000000 --- a/docs/CONTRIBUTING.md +++ /dev/null @@ -1,115 +0,0 @@ -This provides guidance on how to contribute various content to `nuclide.io`. - -## Getting started - -You should only have to do these one time. - -- Rename this file to `CONTRIBUTING.md`. -- Rename `EXAMPLE-README-FOR-RUNNING-DOCS.md` to `README.md` (replacing the existing `README.md` that came with the template). -- Rename `EXAMPLE-LICENSE` to `LICENSE`. -- Checkout the [template information](./TEMPLATE-INFORMATION.md). -- Review `./_config.yml`. -- Make sure you update `title`, `description`, `tagline` and `gacode` (Google Analytics) in `./_config.yml`. - -## Basic Structure - -Most content is written in markdown. You name the file `something.md`, then have a header that looks like this: - -``` ---- -pageid: getting-started -title: Getting started with ProjectName -layout: docs -permalink: /docs/getting-started.html ---- -``` - -Customize these values for each document, blog post, etc. - -> The filename of the `.md` file doesn't actually matter; what is important is the `pageid` being unique and the `permalink` correct and unique too). - -## Landing page - -Modify `index.md` with your new or updated content. - -If you want a `GridBlock` as part of your content, you can do so directly with HTML: - -``` -
-
-
-

Your Features

- -
-
- -
-
-

More information

-

- Stuff here -

-
-
-
-``` - -or with a combination of changing `./_data/features.yml` and adding some Liquid to `index.md`, such as: - -``` -{% include content/gridblocks.html data_source=site.data.features imagealign="bottom"%} -``` - -## Blog - -To modify a blog post, edit the appopriate markdown file in `./_posts/`. - -Adding a new blog post is a four-step process. - -> Some posts have a `permalink` and `comments` in the blog post YAML header. You will not need these for new blog posts. These are an artifact of migrating the blog from Wordpress to gh-pages. - -1. Create your blog post in `./_posts/` in markdown (file extension `.md` or `.markdown`). See current posts in that folder or `./doc-type-examples/2016-04-07-blog-post-example.md` for an example of the YAML format. **If the `./_posts` directory does not exist, create it**. - - You can add a `` tag in the middle of your post such that you show only the excerpt above that tag in the main `/blog` index on your page. -1. If you have not authored a blog post before, modify the `./_data/authors.yml` file with the `author` id you used in your blog post, along with your full name and Facebook ID to get your profile picture. -1. [Run the site locally](./README.md) to test your changes. It will be at `http://127.0.0.1/blog/your-new-blog-post-title.html` -1. Push your changes to GitHub. - -## Docs - -To modify docs, edit the appropriate markdown file in `./_docs/`. - -To add docs to the site.... - -1. Add your markdown file to the `./_docs/` folder. See `./doc-type-examples/docs-hello-world.md` for an example of the YAML header format. **If the `./_docs/` directory does not exist, create it**. - - You can use folders in the `./_docs/` directory to organize your content if you want. -1. Update `_data/nav_docs.yml` to add your new document to the navigation bar. Use the `pageid` you put in your doc markdown in as the `id` in the `_data/nav_docs.yml` file. -1. [Run the site locally](./README.md) to test your changes. It will be at `http://127.0.0.1/docs/your-new-doc-permalink.html` -1. Push your changes to GitHub. - -## Header Bar - -To modify the header bar, change `./_data/nav.yml`. - -## Top Level Page - -To modify a top-level page, edit the appropriate markdown file in `./top-level/` - -If you want a top-level page (e.g., http://your-site.com/top-level.html) -- not in `/blog/` or `/docs/`.... - -1. Create a markdown file in the root `./top-level/`. See `./doc-type-examples/top-level-example.md` for more information. -1. If you want a visible link to that file, update `_data/nav.yml` to add a link to your new top-level document in the header bar. - - > This is not necessary if you just want to have a page that is linked to from another page, but not exposed as direct link to the user. - -1. [Run the site locally](./README.md) to test your changes. It will be at `http://127.0.0.1/your-top-level-page-permalink.html` -1. Push your changes to GitHub. - -## Other Changes - -- CSS: `./css/main.css` or `./_sass/*.scss`. -- Images: `./static/images/[docs | posts]/....` -- Main Blog post HTML: `./_includes/post.html` -- Main Docs HTML: `./_includes/doc.html` diff --git a/docs/Gemfile b/docs/Gemfile deleted file mode 100644 index aed0323a1b..0000000000 --- a/docs/Gemfile +++ /dev/null @@ -1,3 +0,0 @@ -source 'https://rubygems.org' - -gem 'github-pages', '~> 104', group: :jekyll_plugins diff --git a/docs/README.md b/docs/README.md deleted file mode 100644 index df6d45fc41..0000000000 --- a/docs/README.md +++ /dev/null @@ -1,72 +0,0 @@ -## User Documentation for nuclide.io - -This directory will contain the user and feature documentation for Nuclide. The documentation will be hosted on GitHub pages. - -### Contributing - -See [CONTRIBUTING.md](./CONTRIBUTING.md) for details on how to add or modify content. - -### Run the Site Locally - -The requirements for running a GitHub pages site locally is described in [GitHub help](https://help.github.com/articles/setting-up-your-github-pages-site-locally-with-jekyll/#requirements). The steps below summarize these steps. - -> If you have run the site before, you can start with step 1 and then move on to step 5. - -1. Ensure that you are in the `./docs` directory in your local nuclide.io repo clone (i.e., the same directory where this `README.md` exists). The below RubyGems commands, etc. must be run from there. - -1. Make sure you have Ruby and [RubyGems](https://rubygems.org/) installed. - - > Ruby >= 2.2 is required for the gems. On the latest versions of Mac OS X, Ruby 2.0 is the - > default. Use [Homebrew](http://brew.sh) and the `brew install ruby` command (or your - > preferred upgrade mechanism) to install a newer version of Ruby for your Mac OS X system. - -1. Make sure you have [Bundler](http://bundler.io/) installed. - - ``` - # may require sudo - gem install bundler - ``` -1. Install the project's dependencies - - ``` - # run this in the 'docs' directory - bundle install - ``` - - > If you get an error when installing `nokogiri`, you may be running into the problem described - > in [this nokogiri issue](https://github.com/sparklemotion/nokogiri/issues/1483). You can - > either `brew uninstall xz` (and then `brew install xz` after the bundle is installed) or - > `xcode-select --install` (although this may not work if you have already installed command - > line tools). - -1. Run Jekyll's server. - - - On first runs or for structural changes to the documentation (e.g., new sidebar menu item), do a full build. - - ``` - bundle exec jekyll serve --config=_config.yml,_config_local_dev.yml - ``` - - - For content changes only, you can use `--incremental` for faster builds. - - ``` - bundle exec jekyll serve --config=_config.yml,_config_local_dev.yml --incremental - ``` - - > We use `bundle exec` instead of running straight `jekyll` because `bundle exec` will always use the version of Jekyll from our `Gemfile`. Just running `jekyll` will use the system version and may not necessarily be compatible. - - > The `_config_local_dev` file overrides some URL settings that you might be using in production to allow you to test links, etc. locally. - -1. Either of commands in the previous step will serve up the site on your local device at http://127.0.0.1:4000/ or http://localhost:4000. - -### Updating the Bundle - -The site depends on Github Pages and the installed bundle is based on the `github-pages` gem. -Occasionally that gem might get updated with new or changed functionality. If that is the case, -you can run: - -``` -bundle update -``` - -to get the latest packages for the installation. diff --git a/docs/TEMPLATE-INFORMATION.md b/docs/TEMPLATE-INFORMATION.md deleted file mode 100644 index 9175bc0c29..0000000000 --- a/docs/TEMPLATE-INFORMATION.md +++ /dev/null @@ -1,17 +0,0 @@ -## Template Details - -First, go through `_config.yml` and adjust the available settings to your project's standard. When you make changes here, you'll have to kill the `jekyll serve` instance and restart it to see those changes, but that's only the case with the config file. - -Next, update some image assets - you'll want to update `favicon.png`, `logo.svg`, and `og_image.png` (used for Like button stories and Shares on Facbeook) in the `static` folder with your own logos. - -Next, if you're going to have docs on your site, keep the `_docs` and `docs` folders, if not, you can safely remove them (or you can safely leave them and not include them in your navigation - Jekyll renders all of this before a client views the site anyway, so there's no performance hit from just leaving it there for a future expansion). - -Same thing with a blog section, either keep or delete the `_posts` and `blog` folders. - -You can customize your homepage in three parts - the first in the homepage header, which is mostly automatically derived from the elements you insert into your config file. However, you can also specify a series of 'promotional' elements in `_data/promo.yml`. You can read that file for more information. - -The second place for your homepage is in `index.md` which contains the bulk of the main content below the header. This is all markdown if you want, but you can use HTML and Jekyll's template tags (called Liquid) in there too. Checkout this folder's index.md for an example of one common template tag that we use on our sites called gridblocks. - -The third and last place is in the `_data/powered_by.yml` and `_data/powered_by_highlight.yml` files. Both these files combine to create a section on the homepage that is intended to show a list of companies or apps that are using your project. The `powered_by_highlight` file is a list of curated companies/apps that you want to show as a highlight at the top of this section, including their logos in whatever format you want. The `powered_by` file is a more open list that is just text links to the companies/apps and can be updated via Pull Request by the community. If you don't want these sections on your homepage, just empty out both files and leave them blank. - -The last thing you'll want to do is setup your top level navigation bar. You can do this by editing `nav.yml` and keeping the existing title/href/category structure used there. Although the nav is responsive and fairly flexible design-wise, no more than 5 or 6 nav items is recommended. diff --git a/docs/_config.yml b/docs/_config.yml deleted file mode 100644 index 14a279a2fb..0000000000 --- a/docs/_config.yml +++ /dev/null @@ -1,99 +0,0 @@ -# Site settings -permalink: /blog/:year/:month/:day/:title/ -title: Nuclide -tagline: A unified developer experience for web and mobile development -fbappid: "" -gacode: "UA-44373548-2" -description: > - Nuclide is built as a single package on top of Atom to provide hackability and the support of an active community. - - It provides a first-class development environment for React Native, Hack and Flow projects. -logo: /static/og_image.png - -# baseurl determines the subpath of your site. For example if you're using an -# organisation.github.io/reponame/ basic site URL, then baseurl would be set -# as "/reponame". If you have a top-level domain URL, you can set it to "" or -# leave blank as it is now set to "" by default as discussed in: -# http://jekyllrb.com/news/2016/10/06/jekyll-3-3-is-here/ - -# the base hostname & protocol for your site -# If baseurl is set, then the absolute url for your site would be url/baseurl -# This was also be set to the right thing automatically for local development -# https://github.com/blog/2277-what-s-new-in-github-pages-with-jekyll-3-3 -# http://jekyllrb.com/news/2016/10/06/jekyll-3-3-is-here/ -url: "https://nuclide.io" - -# Note: There are new filters in Jekyll 3.3 to help with absolute and relative urls -# absolute_url -# relative_url -# So you will see these used throughout the Jekyll code in this template. -# no more need for | prepend: site.url | prepend: site.baseurl -# http://jekyllrb.com/news/2016/10/06/jekyll-3-3-is-here/ -# https://github.com/blog/2277-what-s-new-in-github-pages-with-jekyll-3-3 - -# The GitHub repo for your project -ghrepo: "facebook/nuclide" - -# Build settings -# Github pages now only supports Kramdown and Rouge -# https://github.com/blog/2100-github-pages-now-faster-and-simpler-with-jekyll-3-0 -# So no need to be explicit with respect to our markdown and highlighter settings since they -# cannot change. -# kramdown also automatically generates header ID's too. But we remove any auto id suffix -# in a post processing step (js/jekyll-link-anchors.js) to make the links more readable. - -# For local development and testing, explicitly set kramdown settings that GitHub does -# https://help.github.com/articles/using-jekyll-with-pages/#defaults-you-can-change -kramdown: - input: GFM - hard_wrap: false - -# Blog posts are built into to Jekyll by default, with the `_posts` directory. -# Here you can specify other types of documentation. The names here are `docs` -# and `top-level`. This means their content will be in `_docs` and `_top-level`. -# The permalink format is also given. -# http://ben.balter.com/2015/02/20/jekyll-collections/ -collections: - docs: - output: true - permalink: /docs/:name/ - top-level: - output: true - permalink: /:name/ - -sass: - style: :compressed - -color: - # Provides colour for background of top header of homepage - primary: "#2F0F56" - # Provides colour for background of elsewhere on site - secondary: "#e4e4e4" - # A color that will work for buttons laid on top of primary colour - light: "#9B4DCA" - # Color that will work for text on top of light color - lighttext: "#fff" - # Color of text in the top header of homepage, must be legible on top of primary color - headertext: "#fff" - # Color of text on top of the secondary color background - bodytext: "#151515" - # Background of fixed nav header - headertext color is used for mini logo text - nav: "#4A148C" - # Text of links in the nav - navtext: "#c79aff" - # Color of link underlines in the main body, and hover background color for links - link: "#6223b0" - -# RSS Feed -gems: - - jekyll-feed - - jekyll-seo-tag - - jekyll-sitemap - -# Set default open graph image for all pages -defaults: - - - scope: - path: "" - values: - image: /static/og_image.png diff --git a/docs/_data/authors.yml b/docs/_data/authors.yml deleted file mode 100644 index 1edcc85aa8..0000000000 --- a/docs/_data/authors.yml +++ /dev/null @@ -1,3 +0,0 @@ -zertosh: - full_name: Andres Suarez - fbid: 18700343 diff --git a/docs/_data/features.yml b/docs/_data/features.yml deleted file mode 100644 index 81d5f2a52f..0000000000 --- a/docs/_data/features.yml +++ /dev/null @@ -1,47 +0,0 @@ -- title: Built-in Debugging - text: | - Building upon Chrome Developer Tools, Nuclide has first class debugging support for React - Native, Hack (shown here), Flow and other platforms. \\ - [**Read More**](/docs/features/debugger) - image: images/docs/promo-debugger.png - -- title: Remote Development - text: | - Connect to your remote servers, and get full access to the file tree within Nuclide. \\ - [**Get Started**](/docs/features/remote/) - image: images/docs/promo-remote-development.png - -- title: Developing JavaScript - text: | - Improve the quality of your JavaScript with built in support for [Flow](http://flowtype.org), - including autocomplete, jump-to-definition, and inline errors. \\ - [**Read More**](/docs/languages/flow/) - image: images/docs/promo-flow.png - -- title: Developing Hack - text: | - Nuclide is the first IDE with support for Hack, including autocomplete, jump-to-definition, - inline errors, and an omni-search bar for your project. \\ - [**Read More**](/docs/languages/hack/) - image: images/docs/promo-hack.png - -- title: Task Runner - text: | - Nuclide's Task Runner is a tool for building, running, testing, and debugging your Buck, Hack, and Swift projects. \\ - [**Read More**](/docs/features/task-runner/) - image: images/docs/promo-task-runner.png - -- title: Working Sets - text: | - Is your project big, but only a small subset applies to your work? Working Sets can reduce - noise. \\ - [**Read More**](/docs/features/working-sets/) - image: images/docs/promo-working-sets.png - -- title: Mercurial Support - text: | - Local changes to files in a Mercurial repo will be reflected in Atom's file tree and UI, as - Atom does natively for Git repos. \\ - [**Read More**](/docs/features/hg/) - image: images/docs/promo-mercurial.png - center: true diff --git a/docs/_data/nav.yml b/docs/_data/nav.yml deleted file mode 100644 index 728312d8c5..0000000000 --- a/docs/_data/nav.yml +++ /dev/null @@ -1,14 +0,0 @@ -- title: Docs - href: /docs/ - category: docs - -- title: Support - href: /support/ - category: support - -- title: GitHub - href: https://github.com/facebook/nuclide - category: external - -# Use external for external links not associated with the paths of the current site. -# If a category is external, site urls, for example, are not prepended to the href, etc. diff --git a/docs/_data/nav_docs.yml b/docs/_data/nav_docs.yml deleted file mode 100644 index d3cb7e4241..0000000000 --- a/docs/_data/nav_docs.yml +++ /dev/null @@ -1,47 +0,0 @@ -- title: Quick Start - items: - - id: quick-start-getting-started - - id: editor-basics -- title: About - items: - - id: editor-setup - - id: editor-keyboard-shortcuts - - id: editor-uninstall - - id: help-faq - - id: help-troubleshooting -- title: Feature Guides - items: - - id: feature-remote - - id: feature-debugger - - id: feature-task-runner - - id: feature-quick-open - - id: feature-working-sets - - id: feature-outline-view - - id: feature-context-view - - id: feature-health -- title: Plugins - items: - - id: feature-hg - - id: feature-toolbar - - id: feature-buck - - id: feature-format-js -- title: Languages - items: - - id: language-hack - - id: language-flow - - id: language-objective-c - - id: language-cpp - - id: language-python - - id: language-swift - - id: language-other -- title: Platforms - items: - - id: platform-ios - - id: platform-android - - id: platform-react-native - - id: platform-web -- title: Advanced Topics - items: - - id: advanced-building-from-source - - id: advanced-custom-keybindings - - id: advanced-linter-package-compatibility diff --git a/docs/_data/promo.yml b/docs/_data/promo.yml deleted file mode 100644 index 011321542f..0000000000 --- a/docs/_data/promo.yml +++ /dev/null @@ -1,12 +0,0 @@ -- type: button - href: docs/quick-start/getting-started/ - text: Getting Started -- type: button - href: docs/platforms/react-native/ - text: React Native -- type: button - href: docs/platforms/ios/ - text: iOS -- type: button - href: docs/platforms/web/ - text: Web diff --git a/docs/_docs/advanced-topics/building-from-source.md b/docs/_docs/advanced-topics/building-from-source.md deleted file mode 100644 index 81b5824fa6..0000000000 --- a/docs/_docs/advanced-topics/building-from-source.md +++ /dev/null @@ -1,123 +0,0 @@ ---- -pageid: advanced-building-from-source -title: Building Nuclide From Source -layout: docs -permalink: /docs/advanced-topics/building-from-source/ ---- - -It is generally recommended to [install the released package of Nuclide](/docs/setup), but for -those willing to live on the bleeding edge, you can install Nuclide from source. - -* TOC -{:toc} - -## Mac - -### Prerequisites - -You must have the [general prerequisites](/docs/editor/setup#mac__prerequisites) installed. In -addition, you must have - -
    -
  • Xcode (for Command Line Tools)
  • -
  • -
  • Atom Shell Commands (open Atom and go to `Atom | Install Shell Commands`) installed as well.
  • -
- -> Xcode can be installed from the App Store. Installation can take a *long, long* time. So be patient. - -> To install Node, the easiest way is to -> [download the latest released Node package](https://nodejs.org) and go through the installer. - -You can verify all the appropriate dependencies. All the following should be in your `$PATH` environment variable (usually `usr/bin` or `usr/local/bin`). - -```bash -$ git --version -$ node --version -$ npm --version -$ apm --version -``` - -> Don't worry about the `apm` versions of `npm`, etc. Those are internal to `atom`. Your -system uses ones associated with `node --version`, etc. - -### Building - -Run the following commands to build Nuclide from source. - -```bash -# Clone the source -$ git clone https://github.com/facebook/nuclide.git -$ cd nuclide -# Install dependencies -$ npm install -# Link the 'nuclide' package to Atom's package directory -# You could also use apm link --dev ... see Development Mode below. -$ apm link -``` - -Verify the installation: - -1. Open Atom. -2. Go to `Atom | Preferences`. -3. Click on **Packages**. -4. Verify `nuclide` is one of the packages. - -## Linux - -### Prerequisites - -You must have the [general prerequisites](/docs/editor/setup#linux__prerequisites) installed. - -

- -To install Node, see [Node.js's download page](https://nodejs.org/en/download/) for steps that work best for your setup. - -You can verify all the appropriate dependencies. All the following should be in your `$PATH` environment variable (usually `usr/bin` or `usr/local/bin`). - -```bash -$ git --version -$ node --version -$ npm --version -$ apm --version -``` - ->Don't worry about the `apm` versions of `npm`, etc. Those are internal to `atom`. Your -system uses the ones associated with `node --version`, etc. - -### Building - -Run the following commands to build Nuclide from source. - -```bash -# Clone the source -$ git clone https://github.com/facebook/nuclide.git -$ cd nuclide -# Install dependencies -$ npm install -# Link the 'nuclide' package to Atom's package directory -# You could also use apm link --dev ... see Development Mode below. -$ apm link -``` - -Verify the installation: - -1. Open Atom. -2. Go to `File | Preferences`. -3. Click on **Packages**. -4. Verify `nuclide` is one of the packages. - -## Windows - -Building Nuclide from source is not currently supported on Windows. - -> It is possible to build Nuclide from source on Windows, but this is done with no guarantee of -> success. The feature set will also be [limited](/docs/editor/setup/#windows). - -## Development Mode - -If you have another version of Nuclide installed (e.g., the official `apm` package), but you also want to run Nuclide from source, you can `apm link --dev` then run Nuclide via `atom --dev`. This will allow something similar to a production and development installation of Nuclide. - -When you open Atom in development mode, either with the `atom --dev` from the command line or with -the `View | Developer | Open in Dev Mode...` command from within the Atom menus, your linked version -of Nuclide will load in place of any other version of Nuclide you might have installed. diff --git a/docs/_docs/advanced-topics/custom-keybindings.md b/docs/_docs/advanced-topics/custom-keybindings.md deleted file mode 100644 index 0ec7a10106..0000000000 --- a/docs/_docs/advanced-topics/custom-keybindings.md +++ /dev/null @@ -1,62 +0,0 @@ ---- -pageid: advanced-custom-keybindings -title: Custom Keybindings -layout: docs -permalink: /docs/advanced-topics/custom-keybindings/ ---- - -Nuclide has a bunch of [built-in bindings](/docs/editor/keyboard-shortcuts) to help you be -productive from the keyboard. However, you may want to add your own keybindings for Nuclide -commands as well. This is fairly easily done with some CSON editing. - -* TOC -{:toc} - -## Keymap CSON - -To create your own keybinding, you will need to edit your `~/.atom/keymap.cson` file. If you aren't -familiar with CSON, it is the [CoffeeScript equivalent of JSON](https://github.com/bevry/cson). - -Here is an example `~/.atom/keymap.cson` file: - -```coffeescript -'.editor:not(.mini)': - 'cmd-d': 'editor:delete-line' - 'cmd-home': 'core:move-to-top' - 'cmd-end': 'core:move-to-bottom' - 'cmd-l': 'go-to-line:toggle' -``` - -Because CSON is a superset of JSON this could also be written as: - -```coffeescript -{ - '.editor:not(.mini)': { - 'cmd-d': 'editor:delete-line', - 'cmd-home': 'core:move-to-top', - 'cmd-end': 'core:move-to-bottom', - 'cmd-l': 'go-to-line:toggle' - } -} -``` - -It may not be obvious, but each key in the top-level map is a CSS selector. Values are pairs of -commands and keybindings that are applicable in an element that matches the CSS selector. The -selector `.editor:not(.mini)` matches an editor in Nuclide that is not used as a single-line input -text box. Therefore, when you want to add a keyboard shortcut for an editor, add it to the -`.editor:not(.mini)` map. - -### Platform Specific Bindings - -You can make your bindings platform specific with `.platform-xxxxx` as part of your CSS selector. -For example the Nuclide `diff-view` CSON looks like this: - -``` -'.platform-darwin atom-workspace': - 'alt-cmd-shift-d': 'nuclide-diff-view:open' - -'.platform-win32 atom-workspace, .platform-linux atom-workspace': - 'alt-ctrl-shift-d': 'nuclide-diff-view:open' -``` - -where `.platform-darwin` represents macOS, `.platform-win32` represents Windows, and `.platform-linux` represents Linux. diff --git a/docs/_docs/advanced-topics/linter-package-compatibility.md b/docs/_docs/advanced-topics/linter-package-compatibility.md deleted file mode 100644 index d2bed3549b..0000000000 --- a/docs/_docs/advanced-topics/linter-package-compatibility.md +++ /dev/null @@ -1,12 +0,0 @@ ---- -pageid: advanced-linter-package-compatibility -title: Linter Package Compatibility -layout: docs -permalink: /docs/advanced-topics/linter-package-compatibility/ ---- - -Nuclide Diagnostics displays diagnostic messages about your code from arbitrary providers. These can be lint warnings, compiler errors, etc. - -Any package that works with the [`linter`](https://atom.io/packages/linter) package should also work with Nuclide Diagnostics. - -We discourage the use of both Nuclide Diagnostics and `linter` together, since you will see duplicate UI for reporting diagnostics. To that end, if you wish to use Nuclide Diagnostics, we recommend disabling the `linter` package. If you wish to continue using the `linter`, we recommend disabling all `nuclide-diagnostics-*` Nuclide features. Please note that doing so will disable some Nuclide capabilities such as Flow and Hack error reporting. diff --git a/docs/_docs/editor/basics.md b/docs/_docs/editor/basics.md deleted file mode 100644 index 26bcce01c9..0000000000 --- a/docs/_docs/editor/basics.md +++ /dev/null @@ -1,246 +0,0 @@ ---- -pageid: editor-basics -title: Basics -layout: docs -permalink: /docs/editor/basics/ ---- - -Nuclide is a code editor built on the backbone of [GitHub's Atom text editor](https://atom.io). -Like other code editors and IDEs, there is a familiar look and feel to Nuclide. On the left side is your project tree, which includes associated files and folders. On the right side is -the main editor that contains the code and text for files in your project. And at the bottom is a -status bar providing quick-look information such as errors, the path of the current file relative -to your project root, the type of file that is open, and other context-aware data. - -![](/static/images/docs/editor-basics-intro.png) - -* TOC -{:toc} - -## Opening - -Assuming you have it [installed](/docs/editor/setup/), Nuclide is opened by opening Atom via mouse -(Dock, Applications folder, etc.) or from the command-line in a terminal window by running: - -```bash -$ atom -``` - -> To enable opening Atom from the command-line, you will need to install shell commands from the -> either the `Atom` menu or the Atom [Command Palette](/docs/editor/basics/#command-palette). In the -> Command Palette, search for "Window: Install Shell Commands". - -To open a specific directory into the [Project Explorer](/docs/editor/basics/#project-explorer), you can add a path argument to the `atom` command. - -```bash -$ atom /path/to/your/project/ -``` - -By default, when you open Nuclide, the Home page appears. - -![](/static/images/docs/editor-basics-homepage.png) - -The Nuclide Home page gives you quick access to common Nuclide tools and features, as well as -information regarding how to provide feedback. - -## Project Explorer - -The Project Explorer is on the left side of Nuclide and contains two tabs: **File Tree** and **Source Control**. This is where you can open projects, navigate through your project to open files in the [Editing Area](#editing-area), create new files and folders, view source control information, etc. - -### Adding Projects - -The first time you open Nuclide, there will be no projects or files open. Instead you will see two options in the Project Explorer's File Tree tab: 1) **Add Project Folder**, which opens a local project, and 2) **Add Remote Project Folder**, which opens a project on a [remote machine](/docs/features/remote/). - -![](/static/images/docs/editor-basics-adding-projects.png) - -When you choose a project to open, you are choosing the root directory of that project. Upon -opening, the project's file tree appears with the root folder at the top. - - - -To remove a project from the Project Explorer, *right-click* on the root folder, and choose **Remove Project Folder**. - -### Multiple Projects - -You can have more than one project open at a time. To open a second project, *right-click* anywhere in the Project Explorer's File Tree area, and choose **Add Project Folder** or **Add Remote Project Folder**. - -> You can have both local and remote projects open at the same time. - -With multiple projects open, default searching for files and in files will span both projects. -However, features such as debugging and error checking will still occur by project. - -> For the `Find | Find In Project` task, you can add project-level granularity by specifying the -> root of the desired project as a filter for the search. - -### Open Files - -The Project Explorer's **Open Files** list displays which files are currently open, allows for quick closure of open files (click on the `x` icon of a file), and indicates which files have unsaved changes (a blue dot in front of the file name). - - - -### Changed Files - -If your project is under source control, the Project Explorer will highlight the files that have changed in your project since your last commit. - -![](/static/images/docs/editor-basics-explorer-changed-files.png) - -#### Uncommitted Changes - -Files that have had changes made to them will also appear in the **Uncommitted Changes** list at the top of the Project Explorer. - - - -#### Source Control - -Under the Project Explorer's **Source Control** tab, you can see if uncommitted changes exist or not. If you are working with a Mercurial repository, the branches are listed as well. - -### Context-Aware Menu - -A context-aware menu appears when you *right-click* in the explorer. This menu provides -options such as adding new projects, searching within the project, opening the current file in -[Diff View](/docs/features/hg/#diff-view) (assuming you are working in a [Mercurial](/docs/features/hg/) repository), etc. - -![](/static/images/docs/editor-basics-explorer-context-aware.png) - -## Editing Area - -The Editing Area is the main area for working with your code and text files. Each file is represented by a -tab. You can split this area into various panes for easier modification of multiple files. -The Editing Area is also where you will find specialized tabs for the Nuclide Home page, -the settings page, etc. - -### File Navigation - -Navigating between files and within files is the same as in -[Atom](https://atom.io/docs/v1.5.0/using-atom-moving-in-atom). - -You can quickly switch between open files by using `Ctrl-Tab` to cycle right or `Ctrl-Shift-Tab` to -cycle left. - -Within files you can go straight to a line number by pressing `Ctrl-G`. If your project uses -a supported language, you can also jump to symbols with `Cmd-R` (`Ctrl-R` on Linux). - -![](/static/images/docs/editor-basics-editing-area-symbols.png) - -### Search - -Most of the searching actions are the same as -[Atom](https://atom.io/docs/v1.5.0/using-atom-find-and-replace). For example, you can search within -a file (i.e., `Cmd-F`) or throughout your entire project(s) (i.e., `Cmd-Shift-F`). - -In addition to the basic Atom searching, Nuclide adds an additional powerful search functionality -that allows you to search in various contexts. OmniSearch (`Cmd-T` on Mac and `Ctrl-T` on Linux) -provides a way to search, all at once, across your project, within your files, code symbols, etc. - -![](/static/images/docs/editor-basics-editing-omnisearch.png) - -### Context-Aware Menu - -A context-aware menu appears when you *right-click* in the Editing Area. This menu provides options such as adding and closing panes, setting and removing breakpoints, showing line-by-line blame (if that information is available), etc. - -![](/static/images/docs/editor-basics-editing-context-aware.png) - -## Status Bar - -The Nuclide status bar builds upon the -[Atom status bar package](https://github.com/atom/status-bar), adding powerful new -features, including code diagnostics and remote connection status. - -![](/static/images/docs/editor-basics-status-bar-intro.png) - -### Code Diagnostics - -If you are using a supported language that provides linting and/or type checking capabilities -(e.g., [Hack](/docs/languages/hack/) or [Flow](/docs/languages/flow/)), then code diagnostics is built directly into Nuclide for that language. - -![](/static/images/docs/editor-basics-status-bar-diagnostics.png) - -### Remote Connection Status - -If you are connected to a project on a remote machine, clicking the Remote Connection icon on -the status bar will provide information about the current status of that connection. Generally, if -all is well, the connection to the server is "healthy". - -![](/static/images/docs/editor-basics-status-bar-connection.png) - -> If you check the connection against a local project, you will get information regarding whether -> the current active file exists on the local filesystem. - -### File Encoding - -The default file encoding for Atom is `UTF-8`. Clicking on this in the status bar allows you to -change the encoding of the current file. - -### Language Selection - -Atom automatically determines the language of the current file. Normally, this is correct. However, you can change -the language, and Atom will change its syntax highlighting appropriately. - -### Branch - -Assuming your project is under source control, the status bar also shows the current branch on -which you are working. - -## Gutter - -Atom has a [gutter](https://atom.io/docs/latest/getting-started-atom-basics#basic-terminology) that -shows you information such as current line number, source control status and function/method -folding. Nuclide has added further features to the gutter, including setting breakpoints for the -debugger and showing diagnostics for supported languages. - -![](/static/images/docs/editor-basics-gutter-intro.png) - -### Code Diagnostics - -If you hover over the code diagnostics errors, an inline window appears showing the problem. - -![](/static/images/docs/editor-basics-gutter-code-diagnostics.png) - -## Preferences Pane - -Nuclide has its own set of customizable preferences and settings. - -You get to these preferences by opening the Atom Settings view via the `Cmd-,` keyboard shortcut -(`Ctrl-,` on Linux) or through the `Packages | Settings View | Open` menu option. - -A new tab opens in the [Editing Area](/docs/editor/basics/#editing-area) titled **Settings**. Select **Packages** from the list at the left of the Settings tab, and scroll down until you see `nuclide` under either **Community Packages** or **Development Packages**. - -![](/static/images/docs/editor-basics-nuclide-package.png) - -> If you linked the [Nuclide source code](https://github.com/facebook/nuclide) to Atom's development -> packages and opened Atom in development mode via the `--dev` flag, you will see the `nuclide` -> package under **Development Packages**. - -Click on **Settings** to see all of the Nuclide preferences and settings. - -![](/static/images/docs/editor-basics-nuclide-preferences.png) - -## Command Palette - -Atom is highly flexible in how you perform actions. Nuclide adds actions as well. There is a -variety of menu options, and many menu commands are equally accessible from the keyboard as well. - -The Command Palette shows you every available command available in Atom and Nuclide. - -`Cmd-Shift-P` toggles the Command Palette. - -![](/static/images/docs/editor-basics-command-palette-intro.png) - -You can narrow down the options that match your search by typing in the text box at the top of the Command Palette. - -![](/static/images/docs/editor-basics-command-palette-search.png) - -## Distraction-Free Mode - -Distraction-Free Mode enables you to eliminate any surrounding panes allowing the [Editing Area](/docs/editor/basics/#editing-area) to take over the entirety of the window without having to toggle panes off individually. - -To use Distraction-Free Mode in your project, click on the **Toggle Distraction-Free Mode** button in the [Nuclide toolbar](/docs/features/toolbar/#buttons). - -Before activating Distraction-Free Mode: - -![](/static/images/docs/editor-basics-distraction.png) - -After activating Distraction-Free Mode: - -![](/static/images/docs/editor-basics-distraction-free.png) - ->If you wish, you can activate other panes after entering Distraction-Free Mode by toggling them on with their [toolbar buttons](/docs/features/toolbar/#buttons) or the [Command Palette](#command-palette). diff --git a/docs/_docs/editor/keyboard-shortcuts.md b/docs/_docs/editor/keyboard-shortcuts.md deleted file mode 100644 index 409d457c60..0000000000 --- a/docs/_docs/editor/keyboard-shortcuts.md +++ /dev/null @@ -1,195 +0,0 @@ ---- -pageid: editor-keyboard-shortcuts -title: Keyboard Shortcuts -layout: docs -permalink: /docs/editor/keyboard-shortcuts/ ---- - -You can perform many tasks in Nuclide from the keyboard. Below are the various keyboard shortcuts -available for the sets of functionality that Nuclide has to offer. - -> Atom has many more keyboard shortcuts available above and beyond what Nuclide offers. To -> get a complete list of the keybindings, you can go to -> `Packages | Settings View | Show Keybindngs`. - -> You can create your own [custom keybindings](/docs/advanced-topics/custom-keybindings) beyond -> those Nuclide provides. - -
- -* TOC -{:toc} - - -## Symbols - -Here is a legend of symbols that are associated with the keys shown in the keybindings. - -| Key | Symbol | -| ----|--------| -| `Alt` or `Option` on macOS | `⌥` | -| `Cmd` on macOS | `⌘` | -| `Ctrl` | `^` | -| `Shift` | `⇧` | -| `Left` | `←` | -| `Up` | `↑` | -| `Right` | `→` | -| `Down` | `↓` | -| `Backspace` | `⌫` | - -If you see a comma (`,`) in a key sequence that means *then*, as in "press this sequence, then press that -sequence". - -## Common Bindings - -These are also described in their respective sections below, but this provides a quick access table -for the most common shortcuts provided by Nuclide. - -| Key (macOS) | Key (Linux) | Description | -|-----------|-------------|-------------| -| `Cmd-T` | `Ctrl-T` | Use [OmniSearch](/docs/features/quick-open/#omnisearch) to open files, etc. | -| `Cmd-\` | `Ctrl-\` | Toggle the [Project Explorer](/docs/editor/basics/#project-explorer). | -| `Ctrl-0` | `Ctrl-0` | Toggle between the [Editing Area](/docs/editor/basics/#editing-area) and the [Project Explorer](/docs/editor/basics/#project-explorer)'s File Tree. | -| `Cmd-K-` | `Ctrl-K-` | Split the current file to the pane represented by ``, where `` is the down, up, left or right arrow. | -| `Option-Shift-Cmd-D` | `Alt-Shift-Ctrl-D` | Open the [Diff View](/docs/features/hg/#diff-view). | -| `Option-Shift-D` | `Alt-Shift-D` | Open the [Code Diagnostics](/docs/editor/basics/#status-bar__code-diagnostics) window. | - -## Development - -These shortcuts provide quick access to development features such as [Diff View](/docs/features/hg/#diff-view), [Code Diagnostics](/docs/editor/basics/#status-bar__code-diagnostics) (e.g, linting), etc. - -| Key (macOS) | Key (Linux) | Command | Description | -|-----------|-------------|---------|-------------| -| `Option-Shift-Cmd-D` | `Alt-Shift-Ctrl-D` | `nuclide-diff-view:open` | This will open the [Diff View](/docs/features/hg/#diff-view), which shows you the difference between the original version of a file and the current version of the file on which changes were made. | -| `Option-O`| `Alt-O` | `nuclide-outline-view:toggle` | Toggles the [Outline View](/docs/features/outline-view/) for a supported file so you can easily navigate to class and function definitions. | -| `Cmd-I` | `Ctrl-I` | `nuclide-context-view:toggle` | Toggles the [Context View](/docs/features/context-view/). | - -### Hack/Flow/JavaScript - -| Key (macOS) | Key (Linux) | Command | Description | -|-----------|-------------|---------|-------------| -| `Option-Shift-Cmd-F` | `Alt-Shift-Ctrl-F` | `nuclide-find-references:activate` | In projects such as Hack or Flow, this will allow you to find all the references to a selected, highlighted entity in your project. | -| `Option-Cmd-Y` | `Alt-Cmd-Y` | `nuclide-hack-symbol-provider:toggle-provider` | Allows you to search for Hack function, classes and constants within you Hack project. -| `Cmd-Shift-I` | `Ctrl-Shift-I` | `nuclide-format-js:format` | Automatically tries to insert missing `require` statements to your [Flow](/docs/languages/flow/) or [JavaScript](/docs/languages/other/#javascript) project. - - -### Code Diagnostics - -| Key (macOS) | Key (Linux) | Command | Description | -|-----------|-------------|---------|-------------| -| `Option-Shift-D` | `Alt-Shift-D` | `nuclide-diagnostics-ui:toggle-table` | Display the window showing you messages about your code. Possible messages include lint, compiler errors, etc. | -| `Option-Shift-A` | `Alt-Shift-A` | `nuclide-diagnostics-ui:fix-all-in-current-file` | Nuclide can fix certain types of problems for you automatically, including various lint problems. This will allow all those to be fixed in the current file. | -| `Option-Ctrl-<` | `Alt-Ctrl-<` | `nuclide-diagnostics-ui:go-to-first-diagnostic` | Go to the first diagnostic. | -| `Option-Ctrl->` | `Alt-Ctrl->` | `nuclide-diagnostics-ui:go-to-last-diagnostic` | Go to the last diagnostic. | -| `Option-<` | `Alt-<` | `nuclide-diagnostics-ui:go-to-previous-diagnostic` | Go to the previous diagnostic. | -| `Option-Ctrl->` | `Alt->` | `nuclide-diagnostics-ui:go-to-next-diagnostic` | Go to the next diagnostic. | - -## Project Explorer's File Tree - -The [Project Explorer](/docs/editor/basics/#project-explorer)'s File Tree tab in the left side pane is a tree of all of your project files. - -| Key (macOS) | Key (Linux) | Command | Description | Alternative | -|-----------|-------------|---------|-------------|-------------| -| `Right` | `Right` | `expand-directory` | Expand the current directory. | `Ctrl-]` | -| `Left` | `Left` | `collapse-directory` | Collapse the current directory. | `Ctrl-[` | -| `Option-Right` | `Alt-Right` | `recursive-expand-directory` | Expand all the directories from the current to the final directory child. | `Ctrl-Alt-]` | -| `Option-Left` | `Alt-Left` | `recursive-collapse-directory` | Collapse all the directories to the top parent. | `Ctrl-Alt-[` -| `Ctrl-{` | `Ctrl-{` | `recursive-collapse-all` | Collapse the entire [Project Explorer](/docs/editor/basics/#project-explorer)'s File Tree to the root. | | -| `Delete` | `Delete` | `remove` | Remove a file or directory from the tree. You will be prompted first to avoid accidental mistakes. | | -| `Cmd-\` | `Ctrl-\` | `toggle` | Toggles whether the [Project Explorer](/docs/editor/basics/#project-explorer)'s File Tree is shown. | `Cmd-K`, `Cmd-B` | -| `Home` | `Home` | `move-to-top` | Move the selection to the very top of the [Project Explorer](/docs/editor/basics/#project-explorer)'s File Tree. | | -| `End` | `End` | `move-to-bottom` | Move the selection to the very bottom of the [Project Explorer](/docs/editor/basics/#project-explorer)'s File Tree. | | -| `Enter` | `Enter` | `open-selected-entry` | Opens the selected entry in the [Project Explorer](/docs/editor/basics/#project-explorer)'s File Tree. If a directory is selected, then the directory is expanded. If a file is selected, then the file is opened in the main [Editing Area](/docs/editor/basics/#editing-area). | | -| `Cmd-K-Down` | `Ctrl-K-Down` | `open-selected-entry-down` | If a file is selected, it opens the file in the bottom pane. | | -| `Cmd-K-Right` | `Ctrl-K-Right` | `open-selected-entry-right` | If a file is selected, it opens the file in the right pane. | | -| `Cmd-K-Up` | `Ctrl-K-Up` | `open-selected-entry-up` | If a file is selected, it opens the file in the top pane. | | -| `Cmd-K-Left` | `Ctrl-K-Left` | `open-selected-entry-left` | If a file is selected, it opens the file in the left pane. | | -| `Cmd-|` | `Ctrl-|` | `reveal-active-file` | Shows the file that is currently active in the main workspace in the [Project Explorer](/docs/editor/basics/#project-explorer)'s File Tree. | `Cmd-Shift-\` (macOS) or `Ctrl-Shift-\` (Linux) -| `Ctrl-O` | `Ctrl-O` | `toggle-focus` | Toggles the focus of the current active file. | | - -## Files - -Whether switching between or searching for or within files, there are some keyboard shortcuts to -help accomplish file tasks a bit faster. - -| Key (macOS) | Key (Linux) | Command | Description | Alternative | -|-----------|-------------|---------|-------------|-------------| -| `Cmd-T` | `Ctrl-T` | `nuclide-quick-open:find-anything-via-omni-search` | Use this for a global search of anything within your project, including all files, currently open files, etc. | `Cmd-P` (macOS) or `Ctrl-P` (Linux) | -| `Option-Cmd-O` | `Alt-Ctrl-O` | `nuclide-open-filenames-provider:toggle-provider` | This lets you switch between files that are currently open in the editor. Useful for quickly accessing files if you have a bunch of files open. | -| `Option-Cmd-R` | `Alt-Ctrl-r` | `nuclide-recent-files-provider:toggle-provider` | This will show you files that you have recently opened and used in previous sessions of Nuclide. | -| `Option-Cmd-T`| `Alt-Ctrl-T` | `nuclide-fuzzy-filename-provider:toggle-provider` | This allows you to search for files based on patterns. | -| `Option-Cmd-N`| `Alt-Ctrl-N` | `nuclide-related-files:jump-to-next-related-file` | Find files related to the current file. A file is related if they have the same basename, but a different extension, for example. | - -## Task Runner - -Nuclide has support for running some common tasks on a variety of projects, like building a Buck project or debugging a React-Native one. For these tasks there is a set of useful keybord shortcuts you can use. - -| Key (macOS) | Key (Linux) | Command | Description | -|-------------|-------------|---------|-------------| -| `Cmd-B B` | `Alt-B B` | `nuclide-task-runner:build` | Executes the Build task for the currently selected Task Runner or the default one| -| `Cmd-B D` | `Alt-B D` | `nuclide-task-runner:debug` | Executes the Debug task for the currently selected Task Runner or the default one| -| `Cmd-B R` | `Alt-B R` | `nuclide-task-runner:run` | Executes the Run task for the currently selected Task Runner or the default one| -| `Cmd-B T` | `Alt-B T` | `nuclide-task-runner:test` | Executes the Test task for the currently selected Task Runner or the default one| -| `Cmd-B P` | `Alt-B P` | `nuclide-task-runner:run-selected-task` | Executes the currently selected Task| - -## Debugger - -The [Nuclide Debugger](/docs/features/debugger/) attaches to a running process. [Breakpoints](/docs/features/debugger/#basics__breakpoints) are managed in the [gutter](/docs/editor/basics/#gutter) to the left of your code and line numbers. - -| Key (macOS) | Key (Linux) | Command | Description | -|-----------|-------------|---------|-------------| -| `Option-Cmd-I` | `Alt-Ctrl-I` | `window:toggle-dev-tools` | Toggle the developer tools UI. | -| `Shift-Cmd-A` | `Shift-Ctrl-A` | `nuclide-debugger:toggle` | Toggles the process attachment UI where you will choose the process on which you would like to debug (e.g., a Node process, etc.) | -| `Cmd-Alt-J` | `Ctrl-Shift-J` | `nuclide-output:toggle` | Toggle the [Console](/docs/features/debugger/#basics__evaluation) pane. | -| `F8` | `F8` | `nuclide-debugger:continue-debugging` | After stopping at a breakpoint, and possibly stepping through code, this will enable debugging to continue to the next breakpoint or end of the process. | -| `F9` | `F9` | `nuclide-debugger:toggle-breakpoint` | If a breakpoint is set, this will unset that breakpoint and vice-versa. | -| `F10` | `F10` | `nuclide-debugger:step-over` | Step over a piece of code. For example, if you are stopped at a method call, this will execute that method without stepping through it line-by-line. | -| `F11` | `F11` | `nuclide-debugger:step-into` | Step into a piece of code. For example, if you are stopped at a method call, this will go into the first line of that method. | -| `Shift-F11` | `Shift-F11` | `nuclide-debugger:step-out` | If you have stepped into a piece of code, this will step out to the point on which you entered that piece of code. For example, if you stepped into a method, this will step out back to the method call itself. | -| `Shift-F5` | `Shift-F5` | `nuclide-debugger:stop-debugging` | Stop the actual debugging process. | - -## Editor Panes - -These are keyboard shortcuts with respect to moving currently active files in the editor around the -main panes. - -| Key (macOS) | Key (Linux) | Command | Description | -|-----------|-------------|---------|-------------| -| `Cmd-K-Down` | `Ctrl-K-Down` | `nuclide-move-pane:move-tab-to-new-pane-down` | Moves the currently active file in the editor to a bottom pane. | -| `Cmd-K-Right` | `Ctrl-K-Right` | `nuclide-move-pane:move-tab-to-new-pane-right` | Moves the currently active file in the editor to a right pane. | -| `Cmd-K-Up` | `Ctrl-K-Up` | `nuclide-move-pane:move-tab-to-new-pane-up` | Moves the currently active file in the editor to a top pane. | -| `Cmd-K-Left` | `Ctrl-K-Left` | `nuclide-move-pane:move-tab-to-new-pane-left` | Moves the currently active file in the editor to a left pane. | - -## Navigation - -These are keyboard shortcuts with respect to navigation within files, etc. - -| Key (macOS) | Key (Linux) | Command | Description | -|-----------|-------------|---------|-------------| -| `Ctrl-,` | `Ctrl-<` | `nuclide-navigation-stack:navigate-backwards` | Moves the cursor to a previous position from the current position. | -| `Ctrl-.` | `Ctrl->` | `nuclide-navigation-stack:navigate-forwards` | Moves the cursor to the next position from the current, but former, position. | - -## Miscellaneous - -These are other key-based shortcuts that are included with Nuclide, including [Hyperclick](#hyperclick), clipboard -and Nuclide health actions. - -| Key (macOS) | Key (Linux) | Command | Description | -|-----------|-------------|---------|-------------| -| `Option-Cmd-Enter` | `Alt-Ctrl-Enter` | `hyperclick:confirm-cursor` | When using [Hyperclick](#hyperclick), this will confirm the Hyperclick action you want to take. | -| `Ctrl-Option-Shift-H` | `Ctrl-Alt-Shift-H` | `nuclide-health:toggle` | Toggle the Nuclide Health tab, which show details about the Nuclide process itself (how much CPU, memory is being used, etc.). | -| `Ctrl-Option-Shift-X` | `Ctrl-Alt-Shift-X` | `nuclide-clipboard-path:copy-project-relative-path` | Copy the relative path of the current file to the clipboard. | -| `Ctrl-Shift-X` | `Ctrl-Shift-X` | `nuclide-clipboard-path:copy-absolute-path` | Copy the absolute path of the current file to the clipboard. | -| `Ctrl-Option-X` | `Ctrl-Alt-X` | `nuclide-clipboard-path:copy-repository-relative-path` | Copy the relative path of the current file starting at the root of the Mercurial repository. | - -### Hyperclick - -Hyperclick Trigger keys are configurable. - -1. Open the [Nuclide Settings](/docs/editor/basics/#preferences-pane) tab either by pressing `Cmd+,` (`Ctrl-,` on Linux) or by going to `Package | Settings View | Open`. -2. Select **Packages** from the list at the left, and search for `nuclide`. -3. Click on the **Settings** button for the `nuclide` package. - -The Hyperclick Trigger key settings are right at the top and set to the defaults. You can change them by clicking on the selection bar and choosing from the provided list. - -![](/static/images/docs/editor-keyboard-shortcuts-hyperclick.png) diff --git a/docs/_docs/editor/setup.md b/docs/_docs/editor/setup.md deleted file mode 100644 index 37e9ace6d6..0000000000 --- a/docs/_docs/editor/setup.md +++ /dev/null @@ -1,189 +0,0 @@ ---- -pageid: editor-setup -title: Setup -layout: docs -permalink: /docs/editor/setup/ ---- - -There are two supported platforms for Nuclide, [Linux](#linux) and [macOS](#macos). - -> Nuclide can be installed on [Windows](#windows), but it is -> [not fully supported](https://github.com/facebook/nuclide/issues/321). - -These instructions are for installing the released package of Nuclide. For advanced users, you can -[build from source](/docs/advanced-topics/building-from-source), but this is not officially -supported and stability is not guaranteed. - -* TOC -{:toc} - -## Quick Install - -

- -Assuming you have met all the prerequisites for your platform, the easiest way to install Nuclide is within Atom itself: - -1. Open Atom. -2. Choose `Atom | Preferences` (`Edit | Preferences` on Linux and `File | Settings` on Windows) to bring up the **Settings** tab. -3. In the **Settings** tab, select **Install** from the list at the left. -4. In the search box, type "Nuclide" and press the `Enter` key. -5. Click the **Install** button for the `nuclide` package. - -> Installing Nuclide within the Atom Packages UI is the recommended method, however you can install Nuclide from the command-line, if you wish, using: -> -```bash -$ apm install nuclide -``` -> - -Otherwise, see your installation platform below for detailed installation instructions, including -prerequisites. - -## macOS - -### Prerequisites - -

- -You can follow the [instructions on the Atom website](http://flight-manual.atom.io/getting-started/sections/installing-atom/#platform-mac). Essentially, -if you go to [Atom.io](https://atom.io/), there will be direct link to download Atom. - -### Installation - -Install Nuclide through the Atom Packages UI: - -1. Open Atom. -2. Choose `Atom | Preferences` to bring up the **Settings** tab. -3. In the **Settings** tab, select **Install** from the list at the left. -4. In the search box, type "Nuclide" and press the `Enter` key. -5. Click the **Install** button for the `nuclide` package. - -![](/static/images/docs/editor-setup-atom-install-nuclide.png) - -> Installing Nuclide within the Atom Packages UI is the recommended method, however you can install Nuclide from the command-line, if you wish, using: -> -```bash -$ apm install nuclide -``` -> - -## Linux - -### Prerequisites - -

- ->Git is required to install Atom on Linux. - -There are [instructions on the Atom website](http://flight-manual.atom.io/getting-started/sections/installing-atom/#platform-linux) for installing Atom on Linux, but it doesn't mention the Git requirement. - -Instead, follow the command-line process below which shows you the installation of all the -necessary prerequisites, including Git. - -This is an installation on Ubuntu. If you are using an RPM-based distro, you should replace the -`apt-get` commands with the appropriate `rpm` or `yum` commands. Depending on your permissions, you -may need to prefix these commands with `sudo`. - -```bash -$ sudo apt-get update -# optional -$ sudo apt-get upgrade -$ sudo apt-get install git -$ sudo add-apt-repository ppa:webupd8team/atom -$ sudo apt-get update -$ sudo apt-get install atom -# Run atom from the command-line if you want -$ atom -``` - -### Installation - -Install Nuclide through the Atom Packages UI: - -1. Open Atom. -2. Choose `Edit | Preferences` to bring up the **Settings** tab. -3. In the **Settings** tab, select **Install** from the list at the left. -4. In the search box, type "Nuclide" and press the `Enter` key. -5. Click the **Install** button for the `nuclide` package. - -> Installing Nuclide within the Atom Packages UI is the recommended method, however you can install Nuclide from the command-line, if you wish, using: -> -```bash -$ apm install nuclide -``` -> - -## Windows - -### Prerequisites - -Atom can be installed on Windows. - -

- -You can follow the [instructions on the Atom website](http://flight-manual.atom.io/getting-started/sections/installing-atom/#platform-windows). Essentially, -if you go to [Atom.io](https://atom.io/), there will be direct link to download Atom. - ->Some features of Nuclide may work on Windows, but the full Nuclide experience is [not yet supported](https://github.com/facebook/nuclide/issues/321). -> ->[Remote development](/docs/features/remote) functionality (seeing the directory tree, editing remote files, etc.) is generally successful on Windows. If you have [Hack](/docs/languages/hack) or [Flow](/docs/languages/flow) on a remote server, it is possible that you could get some of those language integrations to work as well. -> ->However, local projects may run into issues. - -### Installation - -Install Nuclide through the Atom Packages UI: - -1. Open Atom. -2. Choose `File | Settings` to bring up the **Settings** tab. -3. In the **Settings** tab, select **Install** from the list at the left. -4. In the search box, type "Nuclide" and press the `Enter` key. -5. Click the **Install** button for the `nuclide` package. - -![](/static/images/docs/editor-setup-atom-install-windows.png) - -## Post Installation - -After installation, running Atom will automatically load Nuclide. - -### Recommended Packages - -By default, Nuclide does not install all of the recommended Atom packages that enhance the Nuclide -experience. This was done purposely in order to ensure that users have to opt-in to some features -rather than obtrusively modify their work environment. - -Recommended packages include: - -- [`tool-bar`](https://atom.io/packages/tool-bar) to enable the [Nuclide toolbar](/docs/features/toolbar/). -- [`sort-lines`](https://atom.io/packages/sort-lines) to enable sorting lines of text. -- [`language-ocaml`](https://atom.io/packages/language-ocaml) to enable [OCaml](/docs/languages/other/#ocaml) language syntax highlighting. -- [`language-babel`](https://atom.io/packages/language-babel) to enable language grammar for [JS, Flow and React JS](/docs/languages/flow/), etc. -- ...and [others](https://github.com/facebook/nuclide/blob/master/package.json) under `package-deps`. - -
-In order to install all of the recommended packages: - -1. Go to `Packages | Settings View | Manage Packages`. -2. Search for the `nuclide` package, and click on the package's **Settings** button. -3. Select the **Install Recommended Packages on Startup** checkbox. - -![](/static/images/docs/editor-setup-recommended-packages.png) - -### Installing Nuclide Server - -If you want to use Nuclide for remote development, you'll also need to set up the `npm nuclide` -package. Instructions can be found in the [Remote Development docs](/docs/features/remote/). - -### Other Installations - -To benefit from all of Nuclide's features, we recommend you also install the following: - -* [Watchman](https://facebook.github.io/watchman/) - version 3.2 or above. It must be in `/usr/local/bin/` or in your `$PATH` environment variable. - ->Without Watchman, Nuclide will lose some functionality of its [Mercurial](/docs/features/hg), [Remote Development](/docs/features/remote), and [Quick Open](/docs/quick-start/getting-started/#quick-open) features. - -
- -* [Flow](/docs/languages/flow/) -* [Hack](/docs/languages/hack/) -* [Mercurial](/docs/features/hg/) diff --git a/docs/_docs/editor/uninstall.md b/docs/_docs/editor/uninstall.md deleted file mode 100644 index 32c99b2086..0000000000 --- a/docs/_docs/editor/uninstall.md +++ /dev/null @@ -1,43 +0,0 @@ ---- -pageid: editor-uninstall -title: Uninstalling -layout: docs -permalink: /docs/editor/uninstall/ ---- - -To uninstall Nuclide, you run the Atom package manager uninstall command at the command-line: - -```bash -$ apm uninstall nuclide -``` - -> If you have a version of Nuclide prior to 0.0.35, you will need to follow a -> [different process](/docs/help/troubleshooting#uninstalling-older-versions-of-nuclide) to -> uninstall Nuclide. - -## Re-activate Disabled Core Packages - -Nuclide replaces Atom's `tree-view` package in order to support remote file systems. When -uninstalling Nuclide, you need to re-activate the `tree-view` package yourself. The following are -two ways to do that: - -* Re-activate the `tree-view` package through Atom's Settings page. - - 1. Go to `Atom | Preferences` and select **Packages** from the list at the left. - 2. Scroll down to find the `tree-view` package listed under **Core Packages**, or type "tree-view" into the search box. - 3. Click the **Enable** button. - - ![](/static/images/docs/editor-uninstall-reenable-atom-tree-view.png) - -* Edit your Atom `config.cson` file. - - 1. Open `~/.atom/config.cson`. - 2. Remove "tree-view" from the array of `disabledPackages` and save the file. - - ```coffeescript - "*": - core: - disabledPackages: [ - "tree-view" # REMOVE THIS LINE - ] - ``` diff --git a/docs/_docs/features/buck.md b/docs/_docs/features/buck.md deleted file mode 100644 index 6e7533a97b..0000000000 --- a/docs/_docs/features/buck.md +++ /dev/null @@ -1,72 +0,0 @@ ---- -pageid: feature-buck -title: Buck -layout: docs -permalink: /docs/features/buck/ ---- - -Nuclide supports many common workflows with the [Buck](https://buckbuild.com/) -build system. See the [Buck website](https://buckbuild.com/setup/getting_started.html) -for instructions on how to install Buck and create a Buck project. - -* TOC -{:toc} - -## Getting Started - -First, open a Buck project (any project with a `.buckconfig` file) as a project -in Nuclide. - -> [Enabling Buck's httpserver interface](https://buckbuild.com/concept/buckconfig.html#httpserver) -> is recommended for better Buck output in Nuclide. - -If you have multiple projects open, or if your Buck project is a subdirectory -of one of your project roots, you'll need to mark the Buck project root as the -*Current Working Root*. You can do this by right-clicking on the root folder -in the file tree and selecting **Set to Current Working Root**. - -There are a few ways to trigger Buck commands from Nuclide: - -### Via the Task Runner - -Buck tasks live in the [Task Runner toolbar](/docs/features/task-runner). - -Click the **Toggle Task Runner Toolbar** button (i.e., the play icon) from the [Nuclide toolbar](/docs/features/toolbar). Alternatively, - go to `Nuclide | Task Runner | Toggle Toolbar Visibility`. - -Choose any of the Buck tasks from the Task Runner toolbar's drop-down menu. - - - -### Via the Nuclide menu - -The top-level Nuclide menu contains a **Buck** submenu. - - - -### Via Atom's Command Palette - -Open the [Command Palette](/docs/editor/basics/#command-palette) (`Cmd-Shift-P` or `Ctrl-Shift-P` on Linux/Windows) -and type "buck" in the text box: - - - -> You can use these commands to add keybindings in Atom's keymap: -> -> ``` -> 'atom-workspace': -> # note: commands are case-sensitive -> 'cmd-b': 'nuclide-task-runner:toggle-Buck-toolbar' -> 'f5': 'nuclide-task-runner:Buck-build' -> 'f6': 'nuclide-task-runner:Buck-test' -> ... -> ``` - -## Workflows - -Nuclide supports Buck workflows matching the corresponding Buck command-line tasks via the [Task Runner toolbar](/docs/features/task-runner). See the [Task Runner Buck guide](/docs/features/task-runner/#buck) for more information on the following Buck workflows: - -- [Build](/docs/features/task-runner/#buck__build) -- [Run](/docs/features/task-runner/#buck__run) -- [Test](/docs/features/task-runner/#buck__test) -- [Debug](/docs/features/task-runner/#buck__debug) diff --git a/docs/_docs/features/context-view.md b/docs/_docs/features/context-view.md deleted file mode 100644 index e6bd5ef241..0000000000 --- a/docs/_docs/features/context-view.md +++ /dev/null @@ -1,33 +0,0 @@ ---- -pageid: feature-context-view -title: Context View -layout: docs -permalink: /docs/features/context-view/ ---- - -Nuclide provides a Context View to easily navigate between symbol's and their definitions in your code. - - - -
- -* TOC -{:toc} - -## Toggling - -To toggle the Context View panel, you can: - -1. Press `Cmd-I` (`Ctrl-I` on Linux). -2. Go to the `Nuclide | Context View | Toggle` menu. -3. Click on the **Toggle Context View** [button](/docs/features/toolbar/#buttons) on the [Nuclide toolbar](/docs/features/toolbar). - -## Definition Preview - -When you click on a symbol in the [Editing Area](/docs/editor/basics/#editing-area), the symbol's definition will be highlighted in the Context View panel. - -![](/static/images/docs/feature-context-view-highlight.png) - -Clicking on the **Open in main editor** button at the bottom of the Context View panel moves the cursor to that definition be it in the current file or a different one. - -> Context View currently supports [Hack](/docs/languages/hack), [Python](/docs/languages/python), [Objective-C](/docs/languages/objective-c/) and [C++](/docs/languages/cpp) files. diff --git a/docs/_docs/features/debugger.md b/docs/_docs/features/debugger.md deleted file mode 100644 index 4b75a81a57..0000000000 --- a/docs/_docs/features/debugger.md +++ /dev/null @@ -1,206 +0,0 @@ ---- -pageid: feature-debugger -title: Debugger -layout: docs -permalink: /docs/features/debugger/ ---- - -One of the key features of Nuclide is its multiple-language debugging support provided with a debugger interface inspired by the familiar [Chrome DevTools](https://developer.chrome.com/devtools). The Nuclide Debugger provides many capabilities allowing you to have a productive debug loop, including inspection, watches, setting breakpoints, step in/over/out, etc. - -* TOC -{:toc} - -## Instantiation - -In general, the Debugger is instantiated via `Cmd-Shift-A` (`Ctrl-Shift-A` on Linux). You can also -toggle the Debugger through the [Command Palette](/docs/editor/basics/#command-palette) and the -[Nuclide toolbar](/docs/features/toolbar/#buttons)'s **Toggle Debugger** icon. - -## Basics - -Nuclide supports debugging for multiple [languages](#language-specific-debugging) and -[platforms](#platform-specific-debugging). However, there are some basic debugging concepts that apply across all languages. Debugging a Node -project will be used to help illustrate the points described here. - -### Debuggable Target - -Specific details are provided for each [language](#language-specific-debugging) or -[platform](#platform-specific-debugging), but in general, to begin debugging code in Nuclide, you -need to either launch a debug process from within Nuclide (e.g., iOS from the Buck toolbar) or -attach to a currently running process (e.g., `node`) for debugging. - -*Example* - -If you have a Node project running (e.g, via `npm start` or `node yourfile.js`), press -`Cmd-Shift-A` (`Ctrl-Shift-A` on Linux) to toggle the Debugger; this opens the Debugger Selection window. Then, attach Nuclide to the -relevant `node` process. - -![](/static/images/docs/feature-debugger-basics-attach-target-process.png) - -> If you have multiple processes running with the same name, you can use something similar to -> `ps aux | grep ` or Apple's Activity Monitor to find the Process ID (PID) that -> matches with the process in the list in Nuclide's Debugger Selection window. - -Once you attach to a process, you will see a confirmation of the attachment in the command-line for -that process. - -```bash -$ node read.js -Starting debugger agent. -Debugger listening on port 5858 -``` - -After attaching to the process by clicking **Attach**, you should see the Debugger Controls to the right of the [Editing Area](/docs/editor/basics/#editing-area). - -![](/static/images/docs/feature-debugger-target-attach.png) - -### Breakpoints - -To set a breakpoint in Nuclide, you use the [gutter](/docs/editor/basics#gutter). Click to the left -of each line number in the file(s) in which you want Nuclide to break the running program. Then -as the program is running, if a line on which a breakpoint is set is hit, the program halts, and you -are able to perform debugging tasks such as [step](#basics__stepping) and -[evaluation](#basics__evaluation) from that point. - -> There is currently only one type of breakpoint called a *source breakpoint*. This is a breakpoint -> on one line of code. We are looking into ways to support functional, conditional, and other types -> of breakpoints. - -*Example* - -Here we have breakpoints on lines 13 and 18 of `read.js`. - -![](/static/images/docs/feature-debugger-basics-breakpoints-set.png) - -In the [main debugging](#basics__debugger) tab of the Debugger, you will see what -breakpoints are set as well. - -![](/static/images/docs/feature-debugger-basics-breakpoints-debugger-controls.png) - -### Debugger - -The Debugger Controls are the information control center for the Nuclide Debugger. - -In addition to the specialized areas described below, it also provides mouse-clickable execution, -[stepping](#basics__stepping), and breakpoint options. - -***Call Stack*** - -The **Call Stack** area shows you where you came from to get to your current point in the code. The -top function is where you currently are, the function below the top is the one that called the -current function, and so on. Clicking on any function in the call stack will change the scope -information so that it is relevant to that function. - -***Breakpoints*** - -The **Breakpoints** area shows you all the places in your project where you have breakpoints set. If -any are highlighted, that means that you have now hit that breakpoint while running the code. Clicking on a breakpoint in this list will move your cursor to its line of code in the Editing Area. You can deactivate/reactive breakpoints using the green checkmarks next to each one. Right-clicking in the area will give you the option to quickly remove all breakpoints at once. - - - -***Unresolved Breakpoints*** - -These are breakpoints that cannot be resolved by the debugger. The most likely cause of an -unresolved breakpoint is putting a breakpoint on code that is not part of the project on which the -debugger process is attached. - -***Locals*** - -The **Locals** area shows you information about local variables based upon the current point in the running of the code. - -***Watch Expressions*** - -The **Watch Expressions** area is for you to keep track of the values of global and local variables. To add a new value to track, enter it in the `add new watch expression` text box. To remove a watched variable, click the `x` icon of the variable you wish to delete. - -*Example* - -Here we have breakpoints set on line 10 of `read.js` and line 3 of `math.js`. We set watches on two global variables (`num1` and `num2`) in the `read.js` file. The call stack shows that we are -currently in the `processSum` method and started from the `onData` method. - -![](/static/images/docs/feature-debugger-watches-ex.png) - -***Detaching*** - -![](/static/images/docs/feature-debugger-basics-detach.png) - -You can detach the debugger from the current process by clicking the white "X" with the red background in the upper-right corner. -This will stop the entire debugging session for that process. - -***Web Inspector*** - -![](/static/images/docs/feature-debugger-basics-webinspector.png) - -You can open the Web Inspector by clicking on the Web Inspector icon (i.e., gear symbol). This will bring up -a [Chrome Developer Tools window](https://developers.google.com/web/tools/chrome-devtools/) for the -current debugging frame. - -### Stepping - -It is essential for any debugger to have a mechanism to step into, over, and out of code. The -Nuclide Debugger provides stepping functionality with shortcuts within the Debugger itself and -via the [keyboard](/docs/editor/keyboard-shortcuts/#debugger). - -![](/static/images/docs/feature-debugger-stepping-controls.png) - -*Example* - -Assume we have a breakpoint set at line 22 of `read.js` (before the call to `processSum()`). - -![](/static/images/docs/feature-debugger-stepping-line22-ex.png) - -The following shows what happens when you step into the function. The code execution steps into the actual -`processSum()` function itself. - -![](/static/images/docs/feature-debugger-stepping-stepin-ex.png) - -The following shows what happens when you step over the function. `processSum()` is fully executed, -and we move on to closing the `readline` object. - -![](/static/images/docs/feature-debugger-stepping-stepover-ex.png) - -You can even step into a function that exists in another module. - -![](/static/images/docs/feature-debugger-stepping-other-module-ex.png) - -### Evaluation - -The Nuclide Debugger supports -[REPL](https://en.wikipedia.org/wiki/Read%E2%80%93eval%E2%80%93print_loop) via the **Console** tab. - -When you hit a breakpoint during your debugging session, you can use the Console to write -expressions, call functions, etc. using the current state of the program at the breakpoint. - -> For Hack and PHP debugging, hitting a breakpoint is not necessary to use the REPL support of -> the Nuclide Debugger. If you do not hit a breakpoint, then REPL is run in the global context as -> opposed to the current stack frame if a breakpoint is hit. - -> For LLDB-based debugging, REPL runs LLDB debugger commands as opposed to evaluating code in the -> Debugger. - -*Example* - -Here we have a breakpoint before printing out the sum of the two global variables `num1` and `num2`. -This shows printing out the values of the global and local variables, writing simple expressions, -calling a function in another module (`math.add()`), and inspecting objects. - -![](/static/images/docs/feature-debugger-evaluation-ex.png) - -## Language Specific Debugging - -While the [general process](#basics) for debugging in Nuclide is similar, there are platform and -language specific debugging workflows that require discussion and illustration. - -- [Hack and PHP](/docs/languages/hack/#debugging) -- [Flow and JavaScript](/docs/languages/flow/#debugging) (The canonical example for debugging as - described [above](#basics)). -- [C++](/docs/languages/cpp/#debugging) -- [Objective-C](/docs/languages/objective-c/#debugging) - - -## Platform Specific Debugging - -- [React Native](/docs/platforms/react-native/#debugging) -- [iOS](/docs/platforms/ios/#debugging) -- [Android](/docs/platforms/android/#debugging) - -Buck projects can be more easily debugged via the [Task Runner](/docs/features/task-runner/#buck). diff --git a/docs/_docs/features/format-js.md b/docs/_docs/features/format-js.md deleted file mode 100644 index f539b4e070..0000000000 --- a/docs/_docs/features/format-js.md +++ /dev/null @@ -1,55 +0,0 @@ ---- -pageid: feature-format-js -title: Format JS -layout: docs -permalink: /docs/features/format-js/ ---- - ->[Format-js](https://atom.io/packages/nuclide-format-js) is now available as a separate Atom package for use with Nuclide. However, it is currently experimental. For example, this currently does not handle using relative paths for the automatic requires. - -Format-js is a package with a goal of getting rid of worrying about every little formatting detail you might run across while writing -[Flow](/docs/languages/flow) or [JavaScript](/docs/langauges/other/#javascript) code. For more information about the Format-js package visit the [Format-js Atom package page](https://atom.io/packages/nuclide-format-js). - -To install the Format-js package: - -1. Open the [Nuclide Settings](/docs/editor/basics/#preferences-pane) tab either by pressing `Cmd+,` (`Ctrl-,` on Linux) or by going to `Package | Settings View | Open`. -2. Select **Packages** from the list at the left, and search for `nuclide-format-js`. -3. Click **Install**. - -Currently, Format-js is focused on automatically adding, removing, and formatting, your `require` statements. - -## Auto-Require - -Adding `require` statements automatically allows you to focus on writing code without -worrying about that overhead. For example, if you try to use a variable that has not been declared -elsewhere, we will try to add it as a `require`. - -> This assumes the `require` added is a valid module. Of course, it might not be. -> However, something like the [Flow typechecker](/docs/languages/flow) should tell you when you are -> using `require` on an entity that is not a module. - -Take the following code example: - -![](/static/images/docs/feature-format-js-before.png) - -If you press `Cmd-Shift-I` (`Ctrl-Shift-I` on Linux), your code will be analyzed for types that -you are using in your code that may need to be `require`d. The possible `require`s for your code are then added. - -![](/static/images/docs/feature-format-js-after.png) - -You can then check if these are correct and modify accordingly. For example, maybe instead of -`const`, you want `var`. - -## Settings - -There are customizable settings for the Format-js package. - -1. Open the [Nuclide Settings](/docs/editor/basics/#preferences-pane) tab either by pressing `Cmd+,` (`Ctrl-,` on Linux) or by going to `Package | Settings View | Open`. -2. Select **Packages** from the list at the left, and search for `nuclide-format-js`. -3. Click on the **Settings** button for the Format-js package. - -![](/static/images/docs/feature-format-js-settings.png) - -You can also enable or disable keybindings in the Format-js settings. - -![](/static/images/docs/feature-format-js-keybindings.png) diff --git a/docs/_docs/features/health.md b/docs/_docs/features/health.md deleted file mode 100644 index ce69d986fb..0000000000 --- a/docs/_docs/features/health.md +++ /dev/null @@ -1,44 +0,0 @@ ---- -pageid: feature-health -title: Health Statistics -layout: docs -permalink: /docs/features/health-statistics/ ---- - -Nuclide uses computing resources. We try to keep the resource usage as low as possible. One of the -features of Nuclide is a health monitor that allows you to track CPU, memory, heap usage and other -statistics. - -![](/static/images/docs/feature-health-overview.png) - -* TOC -{:toc} - -## Toggling - -To open the **Health** tab in the main [Editing Area](/docs/editor/basics/#editing-area), you have four primary -options: - -- The `Ctrl-Option-Shift-H` (macOS) or `Ctrl-Alt-Shift-H` (Linux) keyboard shortcuts -- The [Nuclide toolbar](/docs/features/toolbar) -- The [Command Palette](/docs/editor/basics/#command-palette) - -## Statistics - -The following statistics are shown in the Nuclide health monitor. If you have multiple Nuclide -sessions open, the statistics are per session and not a combination of all sessions. - -- **CPU**: How much CPU Nuclide is using. -- **Memory**: How much memory Nuclide is using. -- **Heap**: How much of the memory heap given to Node by V8 is being used by Nuclide. -- **Key Latency**: How much time between a key press and the event to occur within Nuclide. -- **Handles**: The number of active handles that still exist in Nuclide. -- **Event Loop**: How many pending requests that Nuclide has. - -The last two statistics are reported by the underlying Atom renderer process and indicate how many -processes, handles, and outstanding activities are currently being managed by Node. - -Also shown are the processes that have been spawned by Nuclide since it has been running, including -process ID (PID), bytes received, sent and the number of errors from the process. - -These statistics are provided by Node's [`process`](https://nodejs.org/api/process.html) APIs. diff --git a/docs/_docs/features/hg.md b/docs/_docs/features/hg.md deleted file mode 100644 index 8fd31707c5..0000000000 --- a/docs/_docs/features/hg.md +++ /dev/null @@ -1,111 +0,0 @@ ---- -pageid: feature-hg -title: Mercurial Support -layout: docs -permalink: /docs/features/hg/ ---- - -Atom provides [Git support](https://atom.io/docs/v1.5.3/using-atom-version-control-in-atom) in its -core packages. Given Facebook's heavy use of Mercurial, Nuclide extends Atom's source control -integration with support for [Mercurial](https://www.mercurial-scm.org/). - -> Nuclide's support for Mercurial is much more full-featured that its support for Git. Nuclide -> has not yet tried to extend the default support for Git provided by Atom. - -
- -* TOC -{:toc} - -## Diff View - -The Diff View allows you to quickly see what has changed in the files you have modified. It -shows what has changed from the current committed revision. - -*Right-click* in the editor and select `Source Control | Open in Diff View` in the context-aware menu (alternatively, you can use `Alt-Cmd-Shift-D` on Mac or `Alt-Ctrl-Shift-D` on Linux). - -![](/static/images/docs/feature-hg-diff-view-access.png) - -The Diff View opens in a new tab in the [Editing Area](/docs/editor/basics/#editing). In the bottom pane are the files that -have been modified, along with the Mercurial commit on which this diff is based. Click on a file -in the bottom pane to see the changes for that file. - -The left pane shows what is currently committed for that file, while the right pane displays what you have -changed. The highlighted sections are the changed lines. - -Here is a picture of the Diff View in action. - -![](/static/images/docs/feature-hg-diff-view-actual.png) - -If you are tracking, for example, a remote bookmark, and you have a stack of diffs that that have -not been pushed to that remote, then the Diff View will show you the entire stack of bookmarks. -If you click on each bookmark, you will see the changes associated with that bookmark and all of its -children, as compared to the remotely tracked bookmark. - -![](/static/images/docs/feature-hg-diff-view-stacked.png) - -## Blame - -Nuclide provides the capability to show you line-by-line -[blame (or annotate)](https://selenic.com/hg/help/annotate) for the current file within your -Mercurial repository. - -*Right-click* in the editor and select `Source Control | Toggle Blame` in the context-aware menu. - -![](/static/images/docs/feature-hg-blame-access.png) - -The [gutter](/docs/editor/basics/#gutter) displays the last commit hash on which there was a change for -the line and the user who made the change. - -![](/static/images/docs/feature-hg-blame-gutter.png) - -## File Tree Highlighting - -To the left of the [Editing Area](/docs/editor/basics/#editing-area) is Nuclide's [Project Explorer](/docs/editor/basics/#project-explorer). The Project Explorer's **File Tree** tab shows you all of the files that are in your project. In a Mercurial project, the File Tree will also show you what files have changed since your last commit. - -If a file is highlighted orange, it indicates a change in that file since your last commit. If a -folder in your project is highlighted orange, that means that files in that folder have changed -since your last commit. Green files or folders are new. Grey files or folders are ignored or -untracked. - -![](/static/images/docs/feature-hg-file-tree-highlight.png) - -## Line Modification Notifications - -This is a built-in Atom feature that displays in the [gutter](/docs/editor/basics/#gutter) showing any lines -that have been modified since the last commit. - ->This feature is not enabled by default. - -To enable this setting: - -1. Open the [Nuclide Settings](/docs/editor/basics/#preferences-pane) tab either by pressing `Cmd+,` (`Ctrl-,` on Linux) or by going to `Package | Settings View | Open`. -2. Select **Packages** from the list at the left, and search for `nuclide`. -3. Click on the **Settings** button for the `nuclide` package. -4. Scroll down until you find `nuclide-hg-repository`, and select the **Enables `git-diff` and `status-bar` diff stats to display added, changed, or removed lines in the editor gutter and status bar** checkbox. - -![](/static/images/docs/feature-hg-line-mod-gutter-setting.png) - -Then, if a line has been modified, you will see an orange vertical line in the gutter, and if a new line of -content has been added, you will see a green vertical line. - -![](/static/images/docs/feature-hg-line-modifications.png) - -## Added and Removed Lines - -This is a built-in Atom feature that displays in the [status bar](/docs/editor/basics/#status-bar) showing the number of lines that have been added and/or removed since the last commit. - -The **+** value is the number of lines that have been added. The **-** value is the number of lines -that have been removed. - -If you change a line (not added or removed), that counts as both an add and a removal, so you -might see something like "+1, -1" for a one line modification. - -![](/static/images/docs/feature-hg-number-of-line-changes.png) - -## Bookmark - -The [status bar](/docs/editor/basics/#status-bars) also shows the current Mercurial bookmark on -which you are currently working. - -![](/static/images/docs/feature-hg-bookmark.png) diff --git a/docs/_docs/features/outline-view.md b/docs/_docs/features/outline-view.md deleted file mode 100644 index 071836a8fd..0000000000 --- a/docs/_docs/features/outline-view.md +++ /dev/null @@ -1,45 +0,0 @@ ---- -pageid: feature-outline-view -title: Outline View -layout: docs -permalink: /docs/features/outline-view/ ---- - -Nuclide provides an Outline View to allow for quick navigation of a code file. This can be -particularly useful for lengthy files with many classes, functions, methods, etc. - - - -* TOC -{:toc} - -## Toggling - -To toggle the **Outline View** panel, you can: - -- Press `Option-O` (`Alt-O` on Linux). -- Go to the `Nuclide | Outline View | Toggle` menu. -- Click on the **Outline View** [button](/docs/features/toolbar/#buttons) within the Nuclide [toolbar](http://nuclide.io/docs/features/toolbar/). -- Use the **Try It** button associated with the **Outline View** [Quick Launch](/docs/quick-start/getting-started/#quick-launch-menu) menu in the Nuclide Home tab. - -## Navigation - -Clicking on any entity in the Outline View will bring you to the line in Nuclide that represents the -beginning of the definition for that entity. For example, clicking on -`function withDestinationPath` in the outline view will bring you to line 44 in the file that -defines that function. - -![](/static/images/docs/feature-outline-view-click.png) - -> Outline View currently supports Hack, PHP, Flow, JavaScript, Python, C++ and JSON files. If you -> have Outline View opened for a file that is not supported, you will see a message similar to -> *"Outline view does not currently support..."* - -## Requirements - -In order for the Outline View to work correctly, the following are required for specific languages: - -- **Hack**: The [Hack typechecker](/docs/languages/hack/#installing-hack), `hh_client`. -- **Flow**: The [Flow typechecker](/docs/languages/flow/#installing-flow), `flow`. -- **Python**: A working installation of [Python](https://www.python.org/), `python`. -- **C++**: One of the [compilers necessary for C++ Nuclide support](/docs/languages/cpp/#supported-compilers). diff --git a/docs/_docs/features/quick-open.md b/docs/_docs/features/quick-open.md deleted file mode 100644 index b010e4fcbb..0000000000 --- a/docs/_docs/features/quick-open.md +++ /dev/null @@ -1,74 +0,0 @@ ---- -pageid: feature-quick-open -title: Quick Open -layout: docs -permalink: /docs/features/quick-open/ ---- - -Nuclide goes beyond just normal file opening capabilities. Quick Open provides multiple -mechanisms to find a file, from recently opened files to a global OmniSearch that lets you search -for anything a file might contain. - -* TOC -{:toc} - -## Toggling - -There are three ways to toggle the **Quick Open** window. - -- The `Cmd-T` (macOS) or `Ctrl-T` (Linux) keyboard shortcuts -- [Command palette](/docs/editor/basics/#command-palette) searching for -`Nuclide Quick Open: Find Anything Via Omni Search` -- [Quick Launch Menu](/docs/quick-start/getting-started/#quick-launch-menu) - -![](/static/images/docs/feature-quick-open-toggle-window.png) - -> The `Hack Symbols` pane will only show if you have [Hack](/docs/languages/hack) files in your -> project. - -## OmniSearch - -*Keyboard Shortcuts*: `Cmd-T` or `Cmd-P` (`Ctrl-T` or `Ctrl-P` on Linux) - -When launching the **Quick Open** window, you will be taken to the **OmniSearch** tab. All of the -features of the other tabs are coalesced and condensed into your search results in this tab. - -![](/static/images/docs/feature-quick-open-omnisearch.png) - -## Filenames - -*Keyboard Shortcut*: `Option-Cmd-T` (`Alt-Ctrl-T` Linux) - -If you just want to search by filename (including within the path to the file) only, you can click -on the **Filenames** tab in the **Quick Open** window. - -![](/static/images/docs/feature-quick-open-filenames.png) - -## Open Files - -*Keyboard Shortcut*: `Option-Cmd-O` (`Alt-Ctrl-O` Linux) - -If you have a lot of files open in your [editor](/docs/editor/basics), you can use the **Open Files** tab of Quick Open to quickly scan a list of your currently open files. - -![](/static/images/docs/feature-quick-open-open-files.png) - -## Recent Files - -*Keyboard Shortcut*: `Option-Cmd-R` (`Alt-Ctrl-R` Linux) - -If you have recently closed a file and would like to quickly open it back up, you can use the -**Recent Files** tab of Quick Open. This tab also displays when you last opened the file(s). - -![](/static/images/docs/feature-quick-open-toggle-recent-files.png) - -## Hack Symbols - -*Keyboard Shortcut*: `Option-Cmd-Y` (`Alt-Ctrl-Y` Linux) - -If your project contains [Hack](/docs/languages/hack) code, you will get Hack language-specific -search options. Here you can search based on function (`@function-name`), class (`#class-name`), or -constant (`%constant-name`) symbols in your project. - -To access this feature, click on the **Hack Symbols** tab in the **Quick Open** window. - -![](/static/images/docs/feature-quick-open-toggle-hack-symbols.png) diff --git a/docs/_docs/features/remote.md b/docs/_docs/features/remote.md deleted file mode 100644 index 4c80eb76dd..0000000000 --- a/docs/_docs/features/remote.md +++ /dev/null @@ -1,136 +0,0 @@ ---- -pageid: feature-remote -title: Remote Development -layout: docs -permalink: /docs/features/remote/ ---- - -In addition to local development, Nuclide supports remote development. Using one of -three authentication methods (Password, an SSH agent, or a private key), you can connect to a -project on a remote machine. This project is then added to your Project Explorer's [File Tree](/docs/editor/basics/#project-explorer) as a remote project where development occurs just it would with a local project. - -* TOC -{:toc} - -## Nuclide Server - -Nuclide has two main components, the client and the optional server. The client is -[set up via an Atom `apm` package](/docs/editor/setup/) on your local machine. The -[server](#nuclide-server__setup) is set up via a Node `npm` package on any machine where you have -remote projects to which Nuclide will connect. - -### Prerequisites - -The remote machine must meet certain prerequisites before the -[remote Nuclide server](#nuclide-server__setup) can be installed. - -
    -
  • [Python](https://www.python.org/) 2.6 or later. In many cases, this will already be installed by -default on your OS distribution.
  • -
  • -
  • `node` and `npm` must be in your `$PATH` environment variable.
  • -
  • [Watchman](https://facebook.github.io/watchman). The Nuclide server -requires Watchman to detect file and directory changes. Follow the Watchman -[build or install instructions](http://facebook.github.io/watchman/docs/install.html#build-install) -for your server's platform.
  • -
  • SSH Daemon - The Nuclide client connects to the server via SSH, so ensure that the server exposes -an SSH daemon that you can connect to from your client machine and that you know the required credentials. You will need to have an existing private key that can be used to connect to the server.
  • -
  • Port 9090-9093 exposed. *Note:* you can specify another port in the **Remote Server Command** box in -the [Connection Dialog box](#remote-connection__connection-dialog-box).
  • -
- -### Setup - -The Nuclide server is installed through an [`npm` package](https://www.npmjs.com/package/nuclide) in -the Node Package Manager. - -```bash -npm install -g nuclide -``` - -> The `-g` switch to ensures Nuclide is installed as a Node global package. - -> While both the client and server packages are named `nuclide`, the `apm` package is the client -> and the `npm` package is the server. - -You do not need to explicitly start the server since the Nuclide client will attempt to do so when -it first connects through one of three authentication methods. - -## Remote Connection - -There are two ways to connect to a project on your remote server. - -If you do not have any projects currently open in Nuclide, you can click on the -**Add Remote Project Folder** button in the Project Explorer's [File Tree](/docs/editor/basics/#project-explorer). - -![](/static/images/docs/feature-remote-add-remote-project-file-tree.png) - -If you have a project already open, you can use `Nuclide | Remote Projects | Connect Remote Project...`, the `Ctrl-Shift-Cmd-C` keyboard shortcut (Mac only), or *right-click* in the Project Explorer's [File Tree](/docs/editor/basics/#project-explorer) and select **Add Remote Project Folder**. - - - -You can also go to the Nuclide Home page, and click the **Try it** button for **Remote Connection** in the [Quick Launch Menu](/docs/editor/getting-started/#quick-launch-menu). - -### Connection Dialog Box - -All the required information to connect to the remote Nuclide server is entered in the Connection -Dialog box. - -![](/static/images/docs/feature-remote-connect-dialog-box.png) - -> All of the values shown above are examples and will vary based on your own username, filesystem, -and SSH and Nuclide configuration. - -The options are as follows: - -- **Username** - the username that you use to connect to your server. -- **Server** - the address of your server. This can be a domain name based or IP address. -- **Initial Directory** - the path on your remote server that contains the project you want to open. -- **SSH Port** - the port used to connect to your server (default is 22). -- **Use ssh-agent-based authentication** - causes the server to try and talk to the ssh agent. -- **Password** - your server password, if you wish to use password authentication. -- **Private Key** - the local path to your private SSH key for this server (*Note:* If your key is -password protected you have to add it to the ssh-agent and use the ssh-agent-based authentication -option). -- **Remote Server Command** - if you have correctly [installed](#nuclide-server__setup) the -[Nuclide server](#nuclide-server), this will be `nuclide-start-server`. If not, you need to -supply the full path to the location of the script. You can either let the script pick an open port -for you from a list of predefined ports, or start the server on a specific port using the -`--port` flag. For example, in this box, you could type `nuclide-start-server --port 9099` (or -similar). - -> Only one of the three authentication options can be chosen and used. - -After supplying these options, click **Connect**. - -### Profiles - -In order to reduce the tediousness of having to specify the same connection information over and -over for machines you connect to frequently, you can use profiles. - -![](/static/images/docs/feature-remote-profiles.png) - -To create a profile, click the **+** button under the **Profiles** list on the left side of the [Connection Dialog box](#remote-connection__connection-dialog-box). - -![](/static/images/docs/feature-remote-add-profile.png) - -Any pre-filled information will be based on your *(default)* profile. Enter all of your connection -information for the new profile (similar to that in the -[Connection Dialog box](#remote-connection__connection-dialog-box)), then click **Save**. - -> `(DEFAULT)` in the **Remote Server Command** box is the default command for the Nuclide server, which -> is `nuclide-start-server`. - -## Development - -Once you have established a [remote connection](#remote-connection) and the Nuclide server is -initiated, the root folder of the project will be added to the Project Explorer's [File Tree](/docs/editor/basics/#project-explorer), underneath any other local (or other -remote) projects you currently have open. - -![](/static/images/docs/feature-remote-file-tree.png) - -Nuclide has now established a connection between your local client and the remote server, and -development can take place as normal. - -> Changes made to a remote file in Nuclide is reflected on the remote machine; changes made in the -> project on the remote server is reflected in your remote project file tree within Nuclide. diff --git a/docs/_docs/features/task-runner.md b/docs/_docs/features/task-runner.md deleted file mode 100644 index a9cd01353e..0000000000 --- a/docs/_docs/features/task-runner.md +++ /dev/null @@ -1,141 +0,0 @@ ---- -pageid: feature-task-runner -title: Task Runner -layout: docs -permalink: /docs/features/task-runner/ ---- - -Nuclide provides the Task Runner toolbar for building, running, testing, and debugging projects. - - -* TOC -{:toc} - -## Buck - -Nuclide supports the [Build](#build), [Run](#run), [Test](#test), and [Debug](#debug) workflows for [Buck](/docs/features/buck), matching the corresponding Buck command-line tasks. - -### Build - -The Build task invokes [`buck build`](https://buckbuild.com/command/build.html), -displaying build output in the [Console](/docs/features/debugger/#basics__evaluation) below the [Editing Area](/docs/editor/basics/#editing-area). - -In the Task Runner toolbar's text box, type in the name of the build target exactly -as you would specify on the command-line, i.e., `//path/to/dir:target_name#flavor`. - -Note that the usual leading `//` is optional. - - - -Clicking on the Settings button (i.e., the gear icon) opens a dialog where you can provide extra flags to Buck. - - - -Upon clicking **Build**, build progress displays via a blue progress bar below the toolbar and also periodically via messages in the [Console](/docs/features/debugger/#basics__evaluation). - -Click the Stop button (i.e., the square icon) at any time to cancel an ongoing build. - - - -In addition to showing up in the [Console](/docs/features/debugger/#basics__evaluation), C++ compilation errors will surface in the [Diagnostics Table](/docs/editor/basics/#code-diagnostics). Buck diagnostics will be cleared upon triggering a new build. - - - -### Run - -The Run task is only enabled for iOS and Android application targets ([`apple_bundle`](https://buckbuild.com/rule/android_binary.html), [`android_binary`](https://buckbuild.com/rule/android_binary.html), and [`apk_genrule`](https://buckbuild.com/rule/apk_genrule.html) rules). It invokes [`buck install --run`](https://buckbuild.com/command/install.html) and builds, installs, then runs the app. Build output will be reported as documented in the [Build workflow](#build) section above. - - - -The iOS simulator type can be explicitly selected via the drop-down menu to the right of the toolbar's Settings button. - -The **React Native Server Mode** checkbox optionally starts the React Native packager -and debugging server while the app installs. - -### Test - -The Test task invokes [`buck test`](https://buckbuild.com/command/test.html), building and running valid test targets (e.g., `cxx_test`). -Build output will be reported as documented in the [Build workflow](#build) section above. - -### Debug - -The Debug task is only enabled for the following target types: - -- iOS applications (`apple_bundle`) -- C++ unit tests (`cxx_test`) -- C++ binaries (`cxx_binary`) - -The [LLDB debugger](/docs/languages/cpp/#debugging) is invoked after a successful build in all three cases, but with slight variations. - -*iOS Applications* - -For iOS applications, the Debug task invokes [`buck install --run --wait-for-debugger`](https://buckbuild.com/command/install.html), then attaches LLDB to the simulator process once the app starts. - -As with the Run task, the iOS simulator type can be selected from the drop-down menu to the right of the toolbar's Settings button. The `React Native Server Mode` checkbox must be selected for React Native apps to enable JavaScript debugging. - -*C++ unit tests* - -For C++ unit tests, LLDB is launched against the unit test binary with the `args` and `env` parameters [specified by the `cxx_test` target](https://buckbuild.com/rule/cxx_test.html) after a successful `buck build`. - -*C++ binaries* - -For C++ binaries, LLDB is launched directly against the output binary after a successful `buck build`. Extra launch arguments can be specified using the Settings button. - - - -## Swift - -The Task Runner toolbar can build [Swift](/docs/languages/swift) packages and run their tests. - -### Building a Swift package - -1. Click the **Toggle Task Runner Toolbar** button on the [Nuclide toolbar](/docs/features/toolbar/#buttons) (or use the [Command Palette](/docs/editor/basics/#command-palette) to issue the **Nuclide Task Runner: Toggle Swift Toolbar** command) to display options for building a Swift package.

-![](/static/images/docs/feature-task-runner-swift-build-toolbar.png) - -2. Select **Build** from the Swift Task drop-down menu. -3. Enter the path to a Swift package's root directory, then click the **Build** button to build the package. (This path is entered automatically if your project root is set to -a Swift package root.) Build output is displayed in the [Console](/docs/features/debugger/#basics__evaluation) below the [Editing Area](/docs/editor/basics/#editing-area). - -![](/static/images/docs/feature-task-runner-swift-build-output.png) - -You can customize build settings, such as whether to build the package in a *Debug* or *Release* configuration, by clicking the Settings button (i.e., the gear icon) to the right -of the toolbar's text box. - -![](/static/images/docs/feature-task-runner-swift-build-settings.png) - -### Running a Swift package's tests - -1. Select **Test** from the Swift Task drop-down menu to display options for running a Swift package's tests.

-![](/static/images/docs/feature-task-runner-swift-test-toolbar.png) - -2. Enter the path to a Swift package's root directory, then click the **Test** button to run the package's tests. (This path is entered automatically if your project root is set -to a Swift package root.) Test output is displayed in the [Console](/docs/features/debugger/#basics__evaluation) below the [Editing Area](/docs/editor/basics/#editing-area). - -![](/static/images/docs/feature-task-runner-swift-test-output.png) - -Clicking the Settings button (i.e., the gear icon) to the right of the toolbar's text box displays additional settings for running your Swift package's tests. - -## HHVM Debug Toolbar - -Nuclide provides an HHVM toolbar in the Task Runner for debugging [Hack](/docs/languages/hack) projects. You can launch the toolbar by clicking the **Toggle Task Runner Toolbar** button in the [Nuclide toolbar](/docs/features/toolbar/#buttons) or from the [Command Palette](/docs/editor/basics/#command-palette) with `Nuclide Task Runner: Toggle HHVM Toolbar`. - -![](/static/images/docs/feature-task-runner-hack-toolbar.png) - -> You must have a Hack or PHP file open to successfully launch the toolbar. - -You can choose either **Attach to WebServer** or **Launch Script** from the drop-down menu. If you select **Attach to WebServer**, the text box will fill automatically with the server to which you are connected. If you select **Launch Script**, the text box will fill automatically with the path of the open file. - - - -Set [breakpoints](/docs/features/debugger/#basics__breakpoints) in your code. - -Click the **Debug** button to open the Debugger; it will stop at the first breakpoint. - -You can then follow the [basic Debugger information](/docs/features/debugger/#basics) and use the additional features of the [Console](/docs/languages/hack/#debugging__console), [Evaluation](/docs/languages/hack/#debugging__evaluation), [Filtering](/docs/languages/hack/#debugging__filtering) and [other HHVM-specific debugging settings]( /docs/languages/hack/#debugging__other-settings) to debug your code. - -![](/static/images/docs/feature-task-runner-hhvm-debug.png) - -In both the script and server launching/attaching scenarios, the line at which you've set a -breakpoint will highlight in blue when the breakpoint is hit. When this happens, execution of your -code is paused and you can use the Debugger Controls to step, evaluate expressions, inspect the current -call stack, etc. diff --git a/docs/_docs/features/toolbar.md b/docs/_docs/features/toolbar.md deleted file mode 100644 index 25718b118d..0000000000 --- a/docs/_docs/features/toolbar.md +++ /dev/null @@ -1,71 +0,0 @@ ---- -pageid: feature-toolbar -title: Toolbar -layout: docs -permalink: /docs/features/toolbar/ ---- - -Nuclide customizes the [tool-bar community Atom package](https://atom.io/packages/tool-bar) for its -specific use. The Nuclide Toolbar provides quick launch access to many common features including -the [Debugger](), [Diff View](), Diagnostics, etc. - -By default, the Nuclide Toolbar is not installed. - -> Internally to Facebook the Toolbar is installed, by default. However, at this point, we did not -> want to presume to install other community packages without the user opting in. - -
- -* TOC -{:toc} - -## Installing - -The Nuclide Toolbar can be installed as part of installing the -[recommended packages](/docs/editor/setup/#post-installation__recommended-packages) through the -Nuclide package settings or it can be installed separately through the normal Atom package -installation process. - -### Singular package - -If you would prefer not to have all of the recommended Nuclide packages installed, you can install -the Toolbar separately. - -1. Go to `Packages | Settings View | Install Packages/Themes`. -2. In the `Search packages` text box, type "tool-bar".

-![](/static/images/docs/feature-toolbar-find-package.png) - -3. Click the **Install** button for the `tool-bar` package. - -The Toolbar will be added to your Nuclide environment (normally either at the top or along the left side of your Atom window). - -### Toggling - -You can toggle the Nuclide Toolbar either through `Packages | Tool Bar | Toggle` or by pressing `Cmd-Option-T` -(`Ctrl-Alt-T` on Linux). - -## Buttons - -The Nuclide Toolbar has buttons that, when clicked, take you to a specific feature of Nuclide. - -| ![](/static/images/docs/feature-toolbar-button-diagnostics.png) | Toggle [Diagnostics](/docs/editor/basics/#status-bar__code-diagnostics) Table | -| ![](/static/images/docs/feature-toolbar-button-outline-view.png) | Toggle [Outline View](/docs/features/outline-view/) | -| | Toggle [Context View](/docs/features/context-view) | -| | Toggle [Task Runner Toolbar](/docs/features/task-runner) | -| | Toggle [Debugger](/docs/features/debugger/) | -| ![](/static/images/docs/feature-toolbar-button-test-runner.png) | Toggle Test Runner | -| | Toggle [Console](/docs/features/debugger/#basics__evaluation) | -| | Open [Diff View](/docs/features/hg/#diff-view) | -| | Toggle [Distraction-Free Mode](/docs/editor/basics/#distraction-free-mode) | -| ![](/static/images/docs/feature-toolbar-button-nuclide-settings.png) | Open [Nuclide Settings](/docs/editor/basics/#preferences-pane) | -| ![](/static/images/docs/feature-toolbar-button-nuclide-health.png) | Toggle [Nuclide health stats](/docs/features/health-statistics/) | - - -## Uninstalling - -You can uninstall the Nuclide Toolbar by following the normal Atom package uninstall mechanism. - -1. Go to `Packages | Settings View | Update Packages/Themes`. -2. Click the **Uninstall** button under the `tool-bar` package. - -> If you [uninstall Nuclide](/docs/editor/uninstall/), the `tool-bar` package is *not* uninstalled. diff --git a/docs/_docs/features/working-sets.md b/docs/_docs/features/working-sets.md deleted file mode 100644 index 3df01c5e2f..0000000000 --- a/docs/_docs/features/working-sets.md +++ /dev/null @@ -1,90 +0,0 @@ ---- -pageid: feature-working-sets -title: Working Sets -layout: docs -permalink: /docs/features/working-sets/ ---- - -It can be common to have a -[large project](/docs/editor/basics/#project-explorer__adding-projects) with a root folder -that has a bunch of children folders and files underneath it. However, your work in that project may only exist in one or a few of the files within the project. The rest of the files are just noise in the [File Tree](/docs/editor/basics/#project-explorer). - -Working Sets allow you to select a subset of folders or files in your project that you -are interested in, hiding all of the other folders and files to display a sparser File Tree. - -* TOC -{:toc} - -## Defining Working Sets - -To define a Working Set, go to the upper right corner of the [Project Explorer](/docs/editor/basics/#project-explorer). As -you move your mouse there, you will see a **+** button appear. - -![](/static/images/docs/feature-working-set-begin.png) - -Clicking on the **+** button toggles the File Tree to allow for selecting folders and files to add to the Working Set you are currently creating. - -After selecting all the folders and files that you want, enter a name for the Working Set in the text box next to the checkmark. - -![](/static/images/docs/feature-working-set-add.png) - -> Click on the **-** button to cancel the creation of the Working Set. - -Once you create the Working Set you will see the File Tree reduced to only those files and folders -that you selected. - -![](/static/images/docs/feature-working-set-created.png) - -You can create as many Working Sets as you like. Just click on the **+** button again. Every time you -create a new Working Set, you will see the entirety of the project tree again for choosing files -and folders. - -> Files and folders can overlap in Working Sets. This might be useful when -> [toggling Working Sets](#toggling-working-sets). - -## Toggling Working Sets - -By default, all Working Sets are active as you create them. This means all of the files and folders -for every Working Set is shown combined in the File Tree. - -Here is an example of three Working Sets shown. - -![](/static/images/docs/feature-working-set-all-working-sets.png) - -However, you can toggle which Working Sets are active. - -![](/static/images/docs/feature-working-set-select-active.png) - -> You can also press `Ctrl-S` or go to `Nuclide | Working Sets | Select Active` to choose your -> active Working Sets. - -To deactivate a Working Set, click on its name. You will see the check mark -disappear, and the folders and files of that Working Set will be removed from the File Tree. - -![](/static/images/docs/feature-working-set-deactivate.png) - -> Pressing `Ctrl-Shift-S` or going to `Nuclide | Working Sets | Toggle Last Selected` will allow -> you to toggle between the full project tree and the currently active Working Set(s). - -## Editing Working Sets - -You can also edit and delete Working Sets. - -![](/static/images/docs/feature-working-set-edit.png) - -By clicking on the trash can, the Working Set is deleted, and if active, the files and folders of -that Working Set will be removed from the File Tree. - -> If a folder or file is part of another active Working Set, then it will remain in the File Tree. - -By clicking on the pencil, you can add or remove folders and files from that Working Set. You can rename the Working Set as well. - -## Opening Non-Working Set Files - -You can open files that do not belong to a Working Set. If, for example, you use -[Quick Open](/docs/features/quick-open) to open a file that is not part of a Working Set, then that file and its parent folders -will be shown *grayed out* in the File Tree. - -![](/static/images/docs/feature-working-set-not-working-set-file.png) - -> If you close the non-Working Set file, it will be removed from the File Tree. diff --git a/docs/_docs/help/faq.md b/docs/_docs/help/faq.md deleted file mode 100644 index 1b26550f4c..0000000000 --- a/docs/_docs/help/faq.md +++ /dev/null @@ -1,227 +0,0 @@ ---- -pageid: help-faq -title: FAQ -layout: docs -permalink: /docs/help/faq/ ---- - -Here is an ever-growing list of frequently asked questions around Nuclide. - -* TOC -{:toc} - -## How do I open Nuclide? - -After ensuring you have Nuclide [set up](/docs/editor/setup/), see the [Opening](/docs/editor/basics/#opening) section in Nuclide [Basics](/docs/editor/basics/) for instructions. - -## What version of Nuclide is installed? - -You can determine the installed version of Nuclide with the [Atom Package Manager](https://github.com/atom/apm) (APM) from the command-line. - -```bash -$ apm list --no-dev --installed -``` - -The output will contain installed Atom packages and their versions. - -```bash -/Users/foobar/.atom/packages (1) -└── nuclide@X.Y.Z -``` - -Your installed version is the number following either the `nuclide` package or the first package -starting with `nuclide-`. In the example above, the installed version is `X.Y.Z`. - -

- -## How do I migrate from a pre-unified package version of Nuclide? - -If you previously installed Nuclide via the `nuclide-installer` package or by installing `nuclide-` -packages individually, you should uninstall them first. - -The new `nuclide` package will automatically disable any deprecated `nuclide-*` packages and warn -you on start up that you should uninstall them to ensure everything works as expected. - -Features you may have been familiar with as separate packages before, such as Hyperclick, -Diagnostics, and File Tree, are now listed as features in Nuclide's Settings page and are togglable -as if they were Atom packages. If you want to use only one or a few of the features of Nuclide, you -can disable the rest of Nuclide without incurring any load time for the disabled features' code. All -features are enabled by default. - - - -### Migrating settings from previous packages - -If you changed settings in any of Nuclide's previous packages, the settings will be automatically -migrated to their new location in the `nuclide.` namespace when you first launch Atom after -installing the `nuclide` package. The settings will be configurable like before but under the -Atom Settings rather than under the package's name. - -## How do I return Nuclide to a known state? - -To reset Atom and Nuclide to factory settings, removing all your packages and settings, do the following: - -1. Quit Atom. -2. Reinstall Atom.app. -3. Reset Atom's settings (optional, but recommended). - - > This will delay any custom settings and packages. - - On your machine, run: - - rm -rf ~/.atom - -4. Reset Atom's cache (optional, but recommended). - On your machine, run: - - rm -rf ~/Library/Application\ Support/Atom - -5. Kill the Nuclide Server (if you have one). - If you are running the Nuclide Server on a remote machine, SSH into it and run: - - pkill -f nuclide - -6. Reinstall Nuclide. - -## How can I make Nuclide like my favorite editor? - -Becaue Nuclide is a package on top of Atom, it is infinitely configurable with a massive collection of open source packages. If you want Atom to behave more like your favorite editor, try one of these: - -* Vim - * [vim-mode-plus](https://atom.io/packages/vim-mode-plus) - * [ex-mode](https://atom.io/packages/ex-mode) -* Emacs - * [emacs-plus](https://atom.io/packages/emacs-plus) - -## Can I write a script to automate basic Atom/Nuclide functionality? - -Atom provides a customizable `init.coffee` script that has full access to the Atom APIs and is executed at startup. For more information, see [Hacking Atom - The Init File](http://flight-manual.atom.io/hacking-atom/sections/the-init-file/). - -You can access the `init.coffee` script by going to `Atom | Init Script...`. - -It's easy to create your own commands with keybindings (you can also configure keybindings in a separate file, see [Keymaps In-Depth](http://flight-manual.atom.io/behind-atom/sections/keymaps-in-depth/)). - ->You have to reload Atom to test your changes. - -## Can the Nuclide Server use ports other than 9090-9093? - -With Nuclide's default server configuration you may run into port number conflicts on your remote server. To specify a specific port for the server to use, you can provide the `--port` option along with the remote server command. - -## Can I print from Nuclide? - -Unfortunately, this is not currently available as an option in Atom and doesn't appear to be something they will be adding. For more information, see [https://discuss.atom.io/t/printing-support/760/45](https://discuss.atom.io/t/printing-support/760/45). - -## How can I make the File Tree always automatically scroll to the current active file? - -1. Open the **Settings** tab either by pressing `Cmd+,` (`Ctrl-,` on Linux) or by going to `Package | Settings View | Open`. -2. Select **Packages** from the list at the left, and search for `nuclide`. -3. Click on the **Settings** button for the `nuclide` package. -4. Scroll down until you find `nuclide-file-tree`. -5. Select the **Reveal File on Switch** checkbox. - - - -## How can I jump to the last cursor position in a file? - -Assume you performed an action that caused the cursor to jump to a new position. How do you go back? - -Use the Nuclide Navigation Stack commands: - -- Forward navigation: `Ctrl-,` (`Ctrl-<` on Linux and Windows) -- Backward navigation: `Ctrl-.` (`Ctrl->` on Linux and Windows) - -## Is there a way to search only files in the Working Set? - -Unfortunately, no. The external search tools Nuclide uses are not aware of the Working Sets. Nuclide also provides the external search tools with the upper limit on result set size preventing purely client-side filtering. - -## How do I disable Most Recently Used tab switching? - -Atom 1.7.0 introducted Most Recently Used (MRU) tab switching. To revert to the old behavior: - -1. Go to `Atom | Keymap...`. This will open the `keympa.cson` file. -2. Add - - 'body': - 'ctrl-tab': 'pane:show-next-item' - 'ctrl-tab ^ctrl': 'unset!' - 'ctrl-shift-tab': 'pane:show-previous-item' - 'ctrl-shift-tab ^ctrl': 'unset!' - -## Can Nuclide save the tabs I have open for each branch/bookmark? - -Yes, Nuclide's Bookshelf feature can save the tabs you have open for each branch/bookmark. When you switch between bookmarks, it will prompt you about restoring the files you had open. - -To control Bookshelf behavior: - -1. Open the **Settings** tab either by pressing `Cmd+,` (`Ctrl-,` on Linux) or by going to `Package | Settings View | Open`. -2. Select **Packages** from the list at the left, and search for `nuclide`. -3. Click on the **Settings** button for the `nuclide` package. -4. Scroll down until you find `nuclide-bookshelf`. -5. Select **Always Restore**, **Always Ignore**, or **Prompt to Restore**. - - - -## Tabs become too small to read the file names when I have many tabs open. - ->This is an issue in Atom. - -One work-around is to make the tabs display in multiple rows. - -1. Go to `Atom | Stylesheet...`. This will open the `styles.less` file. -2. Add - - // Make tabs multi-row - .tab-bar { - height: auto; - flex-wrap: wrap; - .tab, - .tab.active { - flex: 1 0 auto; - height: 30px; - line-height: 27px; - } - .tab .title, - tab.active .title { - padding-right: 5px; - position: relative; - top: 1px; - } - .tab .close-icon, - .tab.active .close-icon { - line-height: 29px; - } - } - -## How do I report bugs, request features, or ask general questions about how to use Nuclide? - -If you've encountered a *bug*, please see the [GitHub Issues page](https://github.com/facebook/nuclide/issues) to see if anyone else has encountered the same problem and to report it as an issue if it is new. - -If you have a *feature request* or *general question*, the [Nuclide Community](https://www.facebook.com/groups/nuclide/) Facebook group is a good place to post. - -## Why is Nuclide a single Atom package? - -The Atom ecosystem is centered around modular packages that can be installed and updated -independently, and Nuclide took that same approach from the start. We wrote scripts to let our code -live in a single repository but be released as many Atom packages. Nuclide releases were actually -simultaneous releases of 40+ Atom packages. While this fit well with the Atom model, it meant we -also had to distribute a "installer" package that oversaw the installation of top-level Atom -packages. - -In practice, the installer process was computationally expensive, difficult to -troubleshoot, and took roughly 40 minutes partially due to large amounts of network traffic. When -all Nuclide packages were installed, they filled over 3GB of disk space. Nuclide packages are -heavily interdependent, and because they were installed as top-level Atom packages they each had -their own 'node_modules' directory with largely duplicate dependencies. - -By unifying Nuclide into a single Atom package, we aimed to improve installation, updates, and -maintenance. The single 'nuclide' package does not require a special installer, only `apm install` -like other Atom packages. This simplifies installation for everyone and makes Nuclide updates fast. -Once installed, the 'nuclide' package takes under 110MB of disk space, a 95%+ reduction in disk use, -and subsequently, network use during installation. The dramatic drop in disk use was possible -because Nuclide's features now share a single 'node_modules' directory and use relative paths to -require one another, eliminating the duplicate dependencies present when Nuclide was 40+ top-level -Atom packages. - -We hope that simplifying the installation -process will make [Nuclide's source](https://github.com/facebook/nuclide) more familiar to other -Atom developers and make it easier for anyone to contribute. diff --git a/docs/_docs/help/troubleshooting.md b/docs/_docs/help/troubleshooting.md deleted file mode 100644 index e13df3fd09..0000000000 --- a/docs/_docs/help/troubleshooting.md +++ /dev/null @@ -1,263 +0,0 @@ ---- -pageid: help-troubleshooting -title: Troubleshooting -layout: docs -permalink: /docs/help/troubleshooting/ ---- - -If you are having problems with Nuclide itself, check out some of these troubleshooting tips. More -are being added as we come across common issues found by users. If you have an issue that is not -listed here, please [file a GitHub issue](https://github.com/facebook/nuclide/issues), and -depending on how widespread the problem may be, we will add it here as well. - -* TOC -{:toc} - -## Help! I think Nuclide is broken. - -It is probably best to [return Nuclide to a known state](/docs/help/faq/#how-do-i-return-nuclide-to-a-known-state). This can solve a variety of bizarre problems. - -## Command-Line Issues - -If `atom` or `apm` don't work from the command line, try removing the `/usr/local/bin/atom` and `/usr/local/bin/npm` symlinks and restarting Atom. Or, select **Install Shell Commands** from the `Atom` menu. - -## Settings Issues - -### Keyboard Shorts aren't working - -* Is the keyboard shortcut registered? - 1. Open the **Settings** tab either by pressing `Cmd-,` (`Ctrl-,` on Linux) or by going to `Package | Settings View | Open`. - 2. Select **Keybindings** from the list at the left to see what keybindings you have active. - -* Check your system keyboard shortcuts. - There may be another application that is intercepting the shortcut before it reaches Atom. - -## Nuclide Server Issues - -### Installation - -If you are having issues installing the [Nuclide Server](/docs/features/remote#nuclide-server), -check out the following tips: - -*Node Version* - -

- -Use the command-line to verify your Node version by running: - -```bash -node --version -``` - -*Permissions* - -If you get `EACCESS` errors when you run the `npm install` command, you likely do not have your NPM properly -configured for installing global packages without root permissions. To fix this problem, install in -a directory your user owns like this: - -```bash -npm config set prefix '~/.npm_packages' -``` - -and add - -```bash -PATH=$PATH:$HOME/.npm_packages/bin; export PATH -``` - -to the end of your `.profile`. Now you should be able to run: - -```bash -npm install -g nuclide -``` - -without errors. - -If you previously ran `npm install` as root, you may need to correct the permissions on your `.npm` -directory by running: - -```bash -sudo chown -R userid:userid .npm -``` - -where `userid` is your userid. If you still get errors you may need to clear your NPM cache with: - -```bash -npm clear cache -``` - -### Files Not Syncing - -Sometimes you'll have a setup that used to work, but starts to fail. Here some things you can try to make it work again: - -* If you have a version mismatch between your client and remote server Nuclide installations, you'll want to run `npm update -g nuclide` on the server and make sure you have the same version on the client as well. -* Other tools that watch files may cause problems as well. Try stopping that process and stopping the file watcher as well via `watchman shutdown-server`. Then try to reconnect to the server again from Atom. -* Use `killall node` on the server side, then try reconnecting. - -## Source Control Issues - -### Source Control features aren't working - -If any Source Control features such as File Tree highlighting are working in Nuclide, there are a few things to check. - -1. Is the directory you opened in Atom part of a source control repository? -2. If you are working on a remote directory, only [Mercurial](/docs/features/hg/) is supported. Git will not work. -3. If the path to the directory you opened in Atom is a symlink, even if it's a Mercurial repository, source control features will not work. As a work-around, use a direct link to the directory to access all the source control features. - -### Why is the output of `hg status` wrong? - -Files not showing up as expected in `hg status` are generally caused by one of a few things: - -1. The file is ignored. - - You can run `hg status -i` to list ignored files. - - hg status -i | grep - -2. Watchman Issues - - Sometimes Watchman, the filesystem monitoring tool, isn't telling Mercurial that a file has been added, removed, or changed. You can check if it's a Watchman issue by running a status command without the Watchman extension: - - hg status --config extensions.fsmonitor=\! - - If the file shows up when you do that, it's a Watchman issue. In that case, run: - - watchman-diag > out.txt - - Sometimes on Macs, the output file might contain: - - There are 139 items on the filesystem not reported by watchman: - ... - - If you see this and if any components of the listed file names either are or were at some point a symlink, then you have fallen afoul of an Apple bug where fsevents won't report changes associated with a dangling symlink. You might be able to recover with: - - watchman watch-del-all - hg --config fsmonitor.mode=off rebase -s '(::bookmark() and draft()) - master::' -d master - watchman watch-project . - -3. Dirstate Corruption - - This happens most often because someone pressed `Ctrl-C` during a Mercurial command that was writing to the dirstate file (an index of all the files in the working directory). This corruption can be subtle and you might not notice any issues with it for a while, until you notice files not showing up that really should. - - In this case, try running: - - hg debugrebuilddirstate --minimal - - Then, run `hg status` again. - -4. Unknown Bugs - - Mercurial is under heavy development and there may be bugs we don't know about yet that cause issues like this. If you've verified that the above things don't work to fix the issue, let us know by filing a [GitHub issue](https://github.com/facebook/nuclide/issues). - -## Environment Issues - -### Uninstalling Older Versions of Nuclide - -[Nuclide v0.0.35](https://github.com/facebook/nuclide/releases/tag/v0.0.35) and earlier were released -as many separate Atom packages. If you have any packages starting with `nuclide-`, you likely have -some part of <=v0.0.35 still installed. - -Run the uninstall command below, which contains the full list of Nuclide's packages when they were -last released on 25 November 2015. This is safe to run even if you only have a subset of the -packages installed; `apm` will ignore any packages that are not present. - -```bash -$ apm uninstall \ -hyperclick \ -nuclide-arcanist \ -nuclide-blame \ -nuclide-blame-provider-hg \ -nuclide-blame-ui \ -nuclide-buck-files \ -nuclide-busy-signal \ -nuclide-clang-atom \ -nuclide-clipboard-path \ -nuclide-code-format \ -nuclide-code-highlight \ -nuclide-debugger-atom \ -nuclide-debugger-hhvm \ -nuclide-debugger-lldb \ -nuclide-diagnostics-store \ -nuclide-diagnostics-ui \ -nuclide-diff-view \ -nuclide-file-tree \ -nuclide-file-watcher \ -nuclide-find-references \ -nuclide-flow \ -nuclide-format-js \ -nuclide-fuzzy-filename-provider \ -nuclide-hack \ -nuclide-hack-symbol-provider \ -nuclide-health \ -nuclide-hg-repository \ -nuclide-home \ -nuclide-installer \ -nuclide-language-hack \ -nuclide-move-pane \ -nuclide-objc \ -nuclide-ocaml \ -nuclide-open-filenames-provider \ -nuclide-quick-open \ -nuclide-react-native-inspector \ -nuclide-recent-files-provider \ -nuclide-recent-files-service \ -nuclide-remote-projects \ -nuclide-test-runner \ -nuclide-toolbar \ -nuclide-type-hint \ -nuclide-url-hyperclick -``` - -## Flow Issues - -### Features Not Working - -If the Flow features are not working in Nuclide: - -- Make sure `flow` is in your [`$PATH`](#flow-issues__flow-and-path) environment variable. -- Ensure that you have `/* @flow */` at the top of your `.js` file. -- Ensure you have an empty `.flowconfig` file in the root of of your project directory. - -### `flow` and `$PATH` - -If you installed `flow` in a place not in your `$PATH` environment variable (e.g., unzipped it in your home directory), then you either have to update your `$PATH` environment variable or explicitly specify it. - -1. Open the **Settings** tab either by pressing `Cmd-,` (`Ctrl-,` on Linux) or by going to `Package | Settings View | Open`. -2. Select **Packages** from the list at the left, and search for `nuclide`. -3. Click on the **Settings** button for the `nuclide` package. -4. Scroll down until you find `nuclide-flow`. -5. Set the location of your `flow` installation in the **Path to Flow Executable** text box. - - - -### Module Not Found - -If you are [running Nuclide from source](/docs/advanced-topics/building-from-source/), you may -occasionally run into a `Cannot find module` error. - -![](/static/images/help/troubleshooting-module-not-found.png) - -As Nuclide is continuously updated, new modules may be added as dependencies. When you rebase to -the latest code and run Nuclide, the new module will not have been installed, so it will not be -found. - -Running `npm update` will get you the latest modules so that you should be able to open Nuclide -successfully again. - -## Buck Issues - -### Nuclide says Diagnostics are disabled, but Buck builds my C++ project - -Stand-alone header files are not fully supported yet because Buck doesn't report flags for them. - ->The majority of features may still work even without complete flags. You can provide more default flags in the Settings, if necessary. - -
- -1. Open the **Settings** tab either by pressing `Cmd-,` (`Ctrl-,` on Linux) or by going to `Package | Settings View | Open`. -2. Select **Packages** from the list at the left, and search for `nuclide`. -3. Click on the **Settings** button for the `nuclide` package. -4. Scroll down until you find `nuclide-clang`. -5. Add default flags as necessary. - - diff --git a/docs/_docs/languages/cpp.md b/docs/_docs/languages/cpp.md deleted file mode 100644 index 6d3b60bfc4..0000000000 --- a/docs/_docs/languages/cpp.md +++ /dev/null @@ -1,212 +0,0 @@ ---- -pageid: language-cpp -title: C++ -layout: docs -permalink: /docs/languages/cpp/ ---- - -Nuclide provides support for C++ developers. - -
- -* TOC -{:toc} - -## Supported Compilers - -In order to get the full features for a C++ project beyond basic syntax highlighting -and a generic autocomplete, you must have the following prerequisites installed: - -1. A compatible build system. You must have one of the following: - * [Buck](http://buckbuild.com) - With no additional setup required! - * [CMake](https://cmake.org/) - You will also have to generate a compilation database with the - [`CMAKE_EXPORT_COMPILE_COMMANDS`](http://clang.llvm.org/docs/JSONCompilationDatabase.html) - option via command-line and place it/symlink it in your project root. - Note that Nuclide does *not* provide any additional CMake integration at the moment. - * You can also manually create a compliant [`compile_commands.json`](http://clang.llvm.org/docs/JSONCompilationDatabase.html) in your project root. -2. [Clang](http://clang.llvm.org/) version 3.6 or higher (we recommend 3.8+) - -### Installing CMake and Clang - -*CMake* - -You can install CMake using one of the [pre-compiled binaries](https://cmake.org/install/) for -Linux and macOS. - -*Clang* - -Clang is generally provided by default on all major Linux distributions. You can use your packaging -system to install it (e.g., `sudo apt-get install clang libclang`). - -Note that **version 3.6 or higher is required**. We recommend 3.8 or above for best results. - -> You can [build Clang from source](http://clang.llvm.org/get_started.html) on Linux as well. - -On macOS, install Clang by installing [Xcode](https://developer.apple.com/xcode/). - -*Verify Install* - -You can verify that Clang is installed by typing `clang++ --version` on the command line. - -> A similar install process occurs for GNU `g++`. It is provided with Xcode, and you can install -> it via a Linux package (e.g., `sudo apt-get install g++`). - -*Building* - -Once Clang is installed, you need to build your C++ project with the `cmake` command, passing in the -`CMAKE_EXPORT_COMPILE_COMMANDS` flag. This will create a `compile_commands.json` file which lives -in the root of your project and provides the necessary information for the -[Nuclide C++ features support](#features). - -> If you use [Buck](#supported-compilers__installing-buck), you will not need to build with this -> flag. - -### Installing Buck - -Buck is [available](https://buckbuild.com/setup/install.html) via Homebrew on macOS, or you can -build from source on Linux. - -*Building* - -Your C++ project must be set up for a Buck build by creating [rules and targets](https://buckbuild.com/about/overview.html). - -## Features - -C++'s Nuclide integration provides you with productivity features such as: - -- [Code Diagnostics](#features__code-diagnostics) -- [Autocomplete](#features__autocomplete) -- [Jump To Declaration](#features__jump-to-declaration) -- [Jump Between Header and Implementation](#features__jump-between-header-and-implementation) -- [Type Hinting](#features__type-hinting) -- [Code Formatting](#features__code-formatting) - -> Remember that these features are only fully-enabled when used with a -> [supported compiler](#supported-compilers). - -### Code Diagnostics - -If you write code that doesn't compile correctly, Nuclide will warn you through its -[Code Diagnostics](/docs/editor/basics/#code-diagnostics) pane, as well with inline -[gutter](/docs/editor/basics/#gutter) tooltips (represented by a sideways red triangle). - -![](/static/images/docs/language-cpp-code-diagnostics.png) - -For [gutter diagnostics](/docs/editor/basics/#gutter), you will sometimes see a **Fix** button. For -some common errors (e.g., a missing semicolon), clicking the **Fix** button will fix the -problem for you. - -In this example, clicking the **Fix** button will insert a semicolon for you. - -![](/static/images/docs/language-cpp-code-diagnostics-gutter-fix.png) - -### Autocomplete - -Nuclide uses metadata from your Clang or Buck build to understand the objects within your project. -This allows for a detailed Autocomplete feature, providing you hints on what is available for a -given object. - -![](/static/images/docs/language-cpp-autocomplete.png) - -### Jump to Declaration - -You can click on a function call for your project and be taken directly to the declaration for that -function. - -Using `Cmd-` or `Cmd-Option-Enter` (`Ctrl-` or `Ctrl-Alt-Enter` on -Linux), the function call will be underlined. - -![](/static/images/docs/language-cpp-jump-to-declaration-link.png) - -Then, you will be taken to the declaration for that function. - -![](/static/images/docs/language-cpp-jump-to-declaration-result.png) - -### Jump Between Header and Implementation - -Using `Cmd-Option-N` (`Ctrl-Alt-N` on Linux), you can jump between the header (`.h`) and -implementation files (`.cpp`). - -### Type Hinting - -If you hover over a variable, Nuclide will show you a datatip with its type. - -![](/static/images/docs/language-cpp-type-hint.png) - -You can pin type hints to the main [Editing Area](/docs/editor/basics/#editing-area) so they -are always shown. - -Click on the pin icon of the type hint to pin the hint and the `x` icon to remove the pinned hint. Pinned type hints can be moved around and placed anywhere in the editing window. - -![](/static/images/docs/language-cpp-type-hint-pinned.png) - -> Hovering over a pinned type hint will highlight the variable associated with it. This is useful -> if you have two pinned type hints for variables on the same line. - -### Code Formatting - -Nuclide will format code based on a set of default Clang standards. - -1. Place your cursor on a function or line of code you wish to format. -2. Press `Cmd-Shift-C` (`Ctrl-Shift-C` on Linux), or use the context-aware menu and choose -**Format Code** to take a piece of code that looks like this... - -![](/static/images/docs/language-cpp-code-formatting-before.png) - -...and format it like this: - -![](/static/images/docs/language-cpp-code-formatting-after.png) - -## Debugging - -Nuclide supports [LLDB](http://lldb.llvm.org/) as the backend for its native C++ debugging. - -> At a minimum, you must have a C++ compiler (e.g., `g++` or `clang++`) and the LLVM Debugger -> (`lldb`) installed to use this feature. For example, on macOS, if you install -> [Xcode](https://developer.apple.com/xcode/) with its command-line tools, these will be installed -> for you. - -> Your C++ code must be compiled with debug symbols. For `g++` or `clang++`, this is accomplished -> by using `-g`. e.g., `clang++ hello.cpp -g -o hello.cpp`. If you are using `cmake` or some other -> build management system, ensure that you are compiling in debug mode with symbols. - -There are three ways to invoke the LLDB debugger: - -- [Attaching to a running process](#attaching-to-a-running-process) -- [Launching a process](#launching-a-process) -- [Debugging a Buck target](#debugging-a-buck-target) - -### Attaching to a running process - -Nuclide can attach to a running C++ process (after -[adding a C++ project](/docs/quick-start/getting-started/#adding-a-project) to Nuclide). Once you -compile your code, run it. - -1. Open the Debugger Selection window by pressing `Cmd-Shift-A` (`Ctrl-Shift-A` on Linux) or by clicking on the **Toggle Debugger** button in the [Nuclide toolbar](/docs/features/toolbar/#buttons). -2. Switch the debugging type to **C++**. -3. Select **Attach** from the **Action** drop-down menu. -4. Find your process in the list, and click the **Attach** button. - - - -After you attach to the process, the Nuclide Debugger appears to the right of the [Editing Area](/docs/editor/basics/#editing-area). -You can then debug your code normally, [following the Debugger guide](/docs/features/debugger/#basics). - -### Launching a process - -Launching a process is similar to the Attach flow. - -1. Open the Debugger Selection window by pressing `Cmd-Shift-A` (`Ctrl-Shift-A` on Linux) or by clicking on the **Toggle Debugger** button in the [Nuclide toolbar](/docs/features/toolbar/#buttons). -2. Switch the debugging type to **C++**. -3. Select **Launch** from the **Action** drop-down menu -4. Fill out the fields, and click the **Launch** button. - - - -### Debugging a Buck target - -See the [Buck guide](/docs/features/buck#debug) for instructions on how to debug C++ Buck targets. - -### LLDB Commands - -You can run LLDB commands directly in the Nuclide Debugger [Console](/docs/features/debugger#basics__evaluation). diff --git a/docs/_docs/languages/flow.md b/docs/_docs/languages/flow.md deleted file mode 100644 index 3f5ce6f6c7..0000000000 --- a/docs/_docs/languages/flow.md +++ /dev/null @@ -1,115 +0,0 @@ ---- -pageid: language-flow -title: Flow -layout: docs -permalink: /docs/languages/flow/ ---- - -Nuclide has deep, built-in support for [Flow-enabled](http://flowtype.org) JavaScript. - ->Flow recently became supported on Windows. See the [Windows is Supported!](https://flowtype.org/blog/2016/08/01/Windows-Support.html) Flow blog post for more information. - -
- -* TOC -{:toc} - -## Installing Flow - -In order to fully use the integration of Flow, you must have Flow installed on your system: - -1. [Install Flow](http://flowtype.org/docs/getting-started.html#installing-flow). -2. If you are new to Flow, [five simple examples](http://flowtype.org/docs/five-simple-examples.html) can get you started writing Flow programs. The -key items of note are: - * The `flow` path is in your `$PATH` environment variable. If it is not in your `$PATH` environment variable for any reason, you can specify the - path to the `flow` binary in `Settings | Packages | Nuclide | Settings | nuclide-flow: Path to Flow Executable`. - * You have an empty `.flowconfig` file in the root of your project. - * You have `/* @flow */` at the top of your JavaScript (`.js`) file. - -## Features - -Flow's integration into Nuclide provides you with productivity features such as: - -* [Code Diagnostics](#features__code-diagnostics) (e.g., inline Flow errors) -* [Autocomplete](#features__autocomplete) -* [Jump to Definition](#features__jump-to-definition) -* [Inline (mouseover) type hinting](#features__type-hinting) -* [Inline type coverage](#features__type-coverage) - -> These features will not work properly unless you are working with Flow-enabled JavaScript since -> they require a `.flowconfig` file in your project root and the ability to run the Flow -> typechecker (e.g., `flow`) from the project root. - -### Code Diagnostics - -If you write code that doesn't pass the Flow typechecker, Nuclide will provide you error details in -both its [Code Diagnostics](/docs/editor/basics/#status-bar__code-diagnostics) pane and inline -within the [Editing Area](/docs/editor/basics/#editing-area). - -![](/static/images/docs/language-flow-code-diagnostics.png) - -Hover over the sideways red triangle in the [gutter](/docs/editor/basics/#gutter) to see the Flow -error inline. - -![](/static/images/docs/language-flow-code-diagnostics-gutter.png) - -### Autocomplete -​​ -Given that Nuclide has access to all of the type information within your project along with the -built-in types provided by Flow, autocomplete just works. - -![](/static/images/docs/language-flow-autocomplete.png) - -By default suggestions from Flow will be shown first in the list of autocomplete results. -However if you don't want this behavior (e.g. you want snippets to be on top), -you can configure priority in Nuclide's preferences. - -### Jump To Definition - -Nuclide provides a jump to definition/symbol feature for Flow programs. - -For example, if you want to go to the definition of `arr_length()`, hover over -`arr_length()`and either press `Cmd-` (`Ctrl-` on Linux) or -`Cmd-Option-Enter` (`Ctrl-Alt-Enter` on Linux). - -![](/static/images/docs/language-flow-jump-to-definition-link.png) - -![](/static/images/docs/language-flow-jump-to-definition-result.png) - -### Type Hinting - -If you hover over a variable in your Flow file, you can get the type of the variable directly -inline. - -![](/static/images/docs/language-flow-typehint.png) - -In fact, you can even pin that type hint so that it always displays. Just click on the pin icon -when hovering over a variable to pin it. - -​​![](/static/images/docs/language-flow-pinned-typehint.png) - -The highlighted variables show that their type variables have been pinned. If you hover over the -type hint, its associated variable will have motion in its highlight. - -Click the `x` icon of a pinned type hint to remove it. - -> Pinned type hints can be moved anywhere within the editor. - -### Type Coverage - -Nuclide can show you how much of your Flow file is covered by the type system with Type Coverage. - -![](/static/images/docs/language-flow-type-coverage.png) - -If the percentage is less than 100%, you can toggle the Type Coverage inline display to show you where the issues are. - -From the [Command Palette](/docs/editor/basics/#command-palette), choose `Nuclide Type Coverage: Toggle Inline Display`. You can also either press `Ctrl-Option-Shift-V` (`Ctrl-Alt-Shift-V` on Linux) or simply click on the percentage displayed in the [Status Bar](/docs/editor/basics/#status-bar). - -Hover over any sideways triangles that appear in the gutter to see the type check issue inline, or open the [Diagnostics Table](/docs/editor/basics/#status-bar__code-diagnostics) to see them all listed together. Clicking on any issue in the Diagnostics Table will highlight the associated line. - -![](/static/images/docs/language-flow-type-coverage-inline.png) - -## Debugging - -The debugging of Flow through Node is a cornerstone of Nuclide. It serves as the example for -the [Debugger](/docs/features/debugger/) at large and is described in the [Debugger Basics](/docs/features/debugger/#basics). diff --git a/docs/_docs/languages/hack.md b/docs/_docs/languages/hack.md deleted file mode 100644 index 1f1fac99de..0000000000 --- a/docs/_docs/languages/hack.md +++ /dev/null @@ -1,248 +0,0 @@ ---- -pageid: language-hack -title: Hack -layout: docs -permalink: /docs/languages/hack/ ---- - -Nuclide has been built from the start to provide a great IDE experience for -[Hack](http://hacklang.org) development. Hack is a programming language for -[HHVM](http://hhvm.com). - -> Currently, HHVM is [not supported on Windows](https://docs.hhvm.com/hhvm/installation/windows), so -> this integration has limited viability on that platform. However, -> [work is being done](https://github.com/facebook/hhvm/issues/5460) to port HHVM to Windows. - -
- -* TOC -{:toc} - -## Installing Hack - -In order to fully use the integration of Hack, you must have both Hack and HHVM installed on your -system: - -1. [Install HHVM](https://docs.hhvm.com/hhvm/installation/introduction). By default, Hack is -installed with HHVM. -2. If you are new to Hack, HHVM's [Getting Started](https://docs.hhvm.com/hack/getting-started/getting-started) provides [steps for writing your first Hack program](https://docs.hhvm.com/hack/getting-started/getting-started#your-first-hack-program). The -key items of note are: - * The typechecker `hh_client` is in your `$PATH` environment variable (the default install of - HHVM, should place it there). - * You have an `.hhconfig` file at the root of your project. - * You have ` If you are planning on developing with Hack [remotely](/docs/features/remote), ensure HHVM and -> Hack are installed on the *remote* machine. - -## Features - -Hack's integration into Nuclide provides you with productivity features such as: - -* [Code Diagnostics](#features__code-diagnostics) -* [Autocomplete](#features__autocomplete) -* [Jump to Definition](#features__jump-to-definition) -* [Inline (mouseover) type hinting](#features__type-hinting) -* [Code formatting](#features__code-formatting) -* [OmniSearch](/docs/features/quick-open), with a special [Hack symbol](/docs/features/quick-open#hack-symbols) search pane. - -### Code Diagnostics - -If your code doesn't correctly [typecheck](https://docs.hhvm.com/hack/typechecker/introduction), Nuclide has code diagnostics that will show you the error. You can see the error in two places, inline within the -[Editing Area](/docs/editor/basics/#editing-area) and in the -[Code Diagnostics](/docs/editor/basics/#status-bar__code-diagnostics) pane below. - -![](/static/images/docs/language-hack-code-diagnostics.png) - -Hover over the sideways red triangle in the [gutter](/docs/editor/basics/#gutter) to see the Hack -error inline. - -![](/static/images/docs/language-hack-code-diagnostics-gutter.png) - -### Autocomplete - -Given that Nuclide has access to all of the type information within your project and the built-in -types provided by Hack, autocomplete just works. - -![](/static/images/docs/language-hack-autocomplete.png) - -### Jump to Definition - -Nuclide provides a jump to definition/symbol feature for Hack programs. - -> In order for this to work, you must have an `.hhconfig` file in the root of your project and a -> running `hh_server` monitoring the root as well. - -For example, if you want to go to the definition of `getPages()`, hover over `getPages()` -and either press `Cmd-` or `Cmd-Option-Enter` (`Ctrl-Alt-Enter` on Linux). - -![](/static/images/docs/language-hack-jump-to-definition-link.png) - -![](/static/images/docs/language-hack-jump-to-definition-result.png) - -### Type Hinting - -If you hover over a variable in your Hack file, you can get the type of the variable directly -inline. - -![](/static/images/docs/language-hack-typehint.png) - -In fact, you can even pin that type hint so that it always displays. Just click on the pin icon -when hovering over a variable to pin it. - -![](/static/images/docs/language-hack-pinned-typehint.png) - -The highlighted variables show that their type variables have been pinned. If you hover over the -type hint, its associated variable will have motion in its highlight. - -Click the `x` icon of a pinned type hint to remove it. - -> Pinned type hints can be moved anywhere within the editor. - -### Type Coverage - -Nuclide can show you how much of your Hack file is covered by the type system with Type Coverage. - -![](/static/images/docs/language-hack-type-coverage.png) - -If the percentage is less than 100%, you can toggle the Type Coverage inline display to show you where the issues are. - -From the [Command Palette](/docs/editor/basics/#command-palette), choose `Nuclide Type Coverage: Toggle Inline Display`. You can also either press `Ctrl-Option-Shift-V` (`Ctrl-Alt-Shift-V` on Linux) or simply click on the percentage displayed in the [Status Bar](/docs/editor/basics/#status-bar). - -Hover over any sideways triangles that appear in the gutter to see the type check issue inline, or open the [Diagnostics Table](/docs/editor/basics/#status-bar__code-diagnostics) to see them all listed together. Clicking on any issue in the Diagnostics Table will highlight the associated line. - -![](/static/images/docs/language-hack-type-coverage-inline.png) - -### Code Formatting - -Nuclide can take your Hack code and format it according to a built-in set of coding standards -(e.g, two-space indents, bracket location, etc.). - -For example, here is a bit of code that looks relatively haphazard from a formatting perspective. - -![](/static/images/docs/language-hack-badly-formatted.png) - -Place your cursor inside the function and press `Cmd-Shift-C` (`Ctrl-Shift-C` on Linux) to apply the coding standards to the function. - -![](/static/images/docs/language-hack-well-formatted.png) - -## Debugging - -Nuclide has support for debugging PHP and Hack projects. [HHVM](https://docs.hhvm.com/hhvm/installation/introduction) is recommended for debugging Hack and PHP code. - -> Theoretically, PHP debugging should work on other XDebug-compatible runtimes like Zend, but we -> have only tested this with HHVM. - -> Currently, we only support debugging [remote](/docs/features/remote/) projects. - -### Xdebug - -In order for the [Nuclide Debugger](/docs/features/debugger) to attach properly to the HHVM process, you must enable -[Xdebug](https://xdebug.org/) in your HHVM configuration. - -> Your remote server may already have the appropriate settings, if so, this step is not necessary. - -You do this by specifying [Xdebug configuration](https://xdebug.org/docs/all_settings) information -in a `.ini` file that will be passed to the HHVM executable. Here is an example `xdebug.ini` file that can -be used: - -```bash -xdebug.enable = 1 -xdebug.remote_enable = 1 -xdebug.remote_autostart = 1 -xdebug.overload_var_dump = 0 -xdebug.remote_port = 9000 -``` - -> In the Nuclide Settings, there is an option to specify the remote port as well. If you specify -> the port in an `.ini` file with `xdebug.remote_port`, make sure it matches what is in the -> Nuclide port setting found under `nuclide-debugger-php`. - -Make sure the **Arguments for your PHP runtime** setting points to your `.ini` file. - -***Example*** - -```bash --c /root/docker-shared/code/xdebug.ini -``` - -The **Path to your PHP runtime** setting should indicate the location of HHVM on your server, such as `/usr/bin/hhvm`. - - -### Debugging: HHVM Toolbar - -The [Task Runner toolbar](/docs/features/task-runner) is one way to debug Hack or PHP projects. To open the Task Runner toolbar, click on the **Toggle Task Runner Toolbar** button in the [Nuclide toolbar](/docs/features/toolbar/#buttons) or search for `Nuclide Task Runner: Toggle HHVM Toolbar` in the [Command Palette](/docs/editor/basics/#command-palette). - -See the [Task Runner HHVM guide](/docs/features/task-runner/#hhvm-debug-toolbar) for instructions on debugging Hack or PHP projects. - -### Debugging: Command-Line - -You can also debug directly from the command-line. - -1. Have a PHP or Hack file active in the [Editing Area](/docs/editor/basics/#editing-area). -2. Click on the **Toggle Debugger** icon in the [Nuclide toolbar](/docs/features/toolbar/#buttons) or press `Cmd-Shift-A` (`Ctrl-Shift-A` on Linux) to bring up the Debugger Selection window. -3. Select the remote server where your project is located from the **Connection** drop-down menu. It should default to the remote location of the PHP or Hack file you have open. -4. Select the file's type from the **Type** drop-down menu. For either PHP or Hack, choose **PHP**. -5. Select **Attach** from the **Action** drop-down menu. - - ![](/static/images/docs/feature-debugger-selection-attach-server.png) - -6. Set [breakpoints](/docs/features/debugger/#basics__breakpoints) in your code. -7. Run your PHP/Hack script or server - 1. If you are running a script: `hhvm -c xdebug.ini your-script.php` - 2. If you are running a server: `hhvm -c xdebug.ini -m server` -8. Start Debugging. - -*Note:* If you are debugging a server, you will need to send a request to that server in order for - the server breakpoint to be hit. - -### Console - -While debugging, HHVM will send its stdout to the Console below the Editing Area. This also includes output from `print()` (or similar) statements and stack traces. - -### Evaluation - -Basic [evaluation](/docs/features/debugger/#basics__evaluation) in the REPL works out of the box. - -You can also load bindings from your project so that you can interact with them in the console. To -do this, make sure there is a `.hhconfig` file checked in at the root of your project, as well as a -`scripts/xdebug_includes.php` file. The `xdebug_includes.php` file must contain at least one call to the -`xdebug_break` function. Here is an example of such a file: - -```php - Linux does not have Xcode. However, there are ways to compile Objective-C programs on Linux using -> `gobjc`, [`gnustep`](http://www.gnustep.org/), etc. - -However, to get the full [feature list](#buck-enabled-features) for Objective-C support, you must -compile your Objective-C program with [Buck](http://buckbuild.com). - -## Default Features - -Objective-C's integration into Nuclide provides you with productivity features out-of-the-box such -as: - -* [Automatic Square Bracket Completion](#default-features__automatic-square-bracket-completion) -* [Automatic Colon Indenting](#default-features__automatic-colon-indenting) - -### Automatic Square Bracket Completion - -If you forget to put a starting bracket at the front of your target or selector, one will be inserted -for you automatically if you add the ending bracket. This will work for any number of bracket -levels deep. - -For example, if you add an ending bracket here... - -![](/static/images/docs/language-objc-before-bracket-insert.png) - -... then the beginning bracket is inserted for you automatically. - -![](/static/images/docs/language-objc-after-bracket-insert.png) - -To enable this setting: - -1. Open the [Nuclide Settings](/docs/editor/basics/#preferences-pane) tab either by pressing `Cmd+,` (`Ctrl-,` on Linux) or by going to `Package | Settings View | Open`. -2. Select **Packages** from the list at the left, and search for `nuclide`. -3. Click on the **Settings** button for the `nuclide` package. -4. Scroll down until you find `nuclide-objc`, and select the **Enable Automatic Square Bracket Completion** checkbox. - -![](/static/images/docs/language-objc-auto-bracket-completion-setting.png) - -### Automatic Colon Indenting - -Nuclide will automatically indent the colons (`:`) associated with new method arguments to be -aligned with the arguments of that method. - -If you start a `:` at the beginning of the next line after the method declaration... - -![](/static/images/docs/language-objc-before-colon-indent.png) - -... it will be aligned automatically. - -![](/static/images/docs/language-objc-after-colon-indent.png) - -## Buck-enabled Features - -The following features require that your Objective-C project is compiled with [Buck](http://buckbuild.com). - -> You can also generate a `compile_commands.json` file with the -> [`json-compilation-databse` reporter](https://github.com/facebook/xctool#included-reporters) -> of [`xctool`](https://github.com/facebook/xctool) to get these features. - -
- -* [Code Diagnostics](#buck-enabled-features__code-diagnostics) -* [Inline Type Hints](#buck-enabled-features__type-hints) -* [Autocomplete](#buck-enabled-features__autocomplete) -* [Jump to Definition](#buck-enabled-features__jump-to-definition) - -> The [Buck toolbar](/docs/features/buck) allows you to build and run your Buck-enabled programs. - -### Code Diagnostics - -If you write code that will cause `clang` errors or warnings, Nuclide's Code Diagnostics will show -you the error. You can see the error in two places: inline within the -[Editing Area](/docs/editor/basics/#editing-area), and in the [Code Diagnostics](/docs/editor/basics/#status-bar__code-diagnostics) pane below. - -![](/static/images/docs/language-objc-code-diagnostics.png) - -Hover over the sideways red triangle in the [gutter](/docs/editor/basics/#gutter) to see the `clang` error inline. - -![](/static/images/docs/language-objc-lint-gutter.png) - -### Type Hints - -Hovering over an Objective-C object will provide you the type of that object inline. - -![](/static/images/docs/language-objc-typehint.png) - -In fact, you can even pin that type hint so that it always displays. Just click on the pin icon when hovering over a variable to pin it. - -![](/static/images/docs/language-objc-pinned-typehint.png) - -Click the `x` icon of a pinned type hint to remove it. - -> Pinned type hints can be moved anywhere within the editor. - -### Autocomplete - -Buck enhances the understanding of the types of objects in your project so that autocomplete can be -enabled. - -![](/static/images/docs/language-objc-autocomplete.png) - -> Without Buck, you will still get the default autocomplete feature, but without project and object -> specific information. - -### Jump To Definition - -Nuclide provides a jump to definition/symbol feature for Objective-C programs. - -For example, if you want to go to the definition of `initWithHelloString:`, hover over -`initWithHelloString:` and either press `Cmd-` (`Ctrl-` on Linux) or -`Cmd-Option-Enter` (`Ctrl-Alt-Enter` on Linux). - -![](/static/images/docs/language-objc-jump-to-definition-link.png) - -![](/static/images/docs/language-objc-jump-to-definition-result.png) - -### Jump Between Header and Implementation - -Using `Cmd-Option-N` (`Ctrl-Alt-N` on Linux), you can jump between the header (i.e., `.h`) and -the implementation (i.e., `.cpp` or `.m`) files. - -## Debugging - -Nuclide has support for both [iOS](/docs/platforms/ios) debugging through -[React Native](/docs/platforms/react-native/#debugging) and [Buck](http://buckbuild.com) -for native Objective-C applications (i.e., `.m` files). - -> Debugging Swift applications is currently not supported. - -See the [Buck guide](/docs/features/buck) for how to build, run and debug iOS apps. - -> Optimally, it would be nice to run the application directly from Xcode and attach to the -> simulator process associated with that Xcode project. However, due to `lldb` process conflict -> issues, this is currently not possible. - -### LLDB Commands - -Native iOS debugging uses [LLDB](http://lldb.llvm.org/) as its debugging backend. You can run LLDB -commands directly in the Nuclide Debugger's [Console](/docs/features/debugger#basics__evaluation). diff --git a/docs/_docs/languages/other.md b/docs/_docs/languages/other.md deleted file mode 100644 index 96169ea7e4..0000000000 --- a/docs/_docs/languages/other.md +++ /dev/null @@ -1,49 +0,0 @@ ---- -pageid: language-other -title: PHP, JS, OCaml -layout: docs -permalink: /docs/languages/other/ ---- - -Nuclide provides support for other languages as well. Some of these are not as full-featured as -similar languages (e.g., Hack vs PHP); others are experimental. - -* TOC -{:toc} - -## PHP - -Nuclide's PHP support is similar to its support for [Hack](/docs/languages/hack), except you will -not get as full-featured diagnostics, type hinting, etc. since there is no -[typechecker](https://docs.hhvm.com/hack/typechecker/introduction) to assist Nuclide with your project's metadata. - -## JavaScript - -Nuclide's JavaScript support is similar to its support for [Flow](/docs/languages/flow), except -you will not get as full-featured diagnostics, type hinting, etc. since there is no -[typechecker](http://flowtype.org/) to assist Nuclide with your project's metadata. -[Debugging through Node](/docs/features/debugger/#basics) is similar to -[Flow](/docs/languages/flow/#debugging) as well. - -JavaScript is a primary language for [React Native](https://facebook.github.io/react-native/), and -Nuclide is a great IDE for [developing React Native applications](/docs/platforms/react-native). - -## OCaml - -This **experimental** feature provides rudimentary support for OCaml via -[ocamlmerlin](https://github.com/the-lambda-church/merlin). Merlin can be installed from source -or by installing the `merlin` OPAM package. - -OCaml's integration into Nuclide provides you with productivity features such as: - -* Autocomplete -* Jump to Definition - -It requires that `ocamlmerlin` be installed on your system and properly configured for your -project. `ocamlmerlin` should be in your `$PATH` environment variable. If it is not, you may specify the path to -`ocamlmerlin` in the settings for the 'nuclide' package. - -1. Open the [Nuclide Settings](/docs/editor/basics/#preferences-pane) tab either by pressing `Cmd+,` (`Ctrl-,` on Linux) or by going to `Package | Settings View | Open`. -2. Select **Packages** from the list at the left, and search for `nuclide`. -3. Click on the **Settings** button for the `nuclide` package. -4. Scroll down until you find `nuclide-ocaml`, and enter the custom path in the **Path to Merlin Executable** text box. diff --git a/docs/_docs/languages/python.md b/docs/_docs/languages/python.md deleted file mode 100644 index 73517a4f3d..0000000000 --- a/docs/_docs/languages/python.md +++ /dev/null @@ -1,103 +0,0 @@ ---- -pageid: language-python -title: Python -layout: docs -permalink: /docs/languages/python/ ---- - -Nuclide has well-rounded support for Python 2 and 3. - -* TOC -{:toc} - -## Using Python Features with Buck Projects - -If your code uses Buck to manage Python dependencies, you will need to build -your project's `python_binary` target in order for autocomplete and -jump to definition to find results from dependencies. - -## Features - -Python's integration into Nuclide provides you with productivity features such as: - -- [Autocomplete](#features__autocomplete) -- [Jump To Definition](#features__jump-to-definition) -- [Code Formatting](#features__code-formatting) -- [Code Diagnostics](#features__code-diagnostics) -- [Outline View](#features__outline-view) - -### Autocomplete - -Nuclide integrates [Jedi](http://jedi.jedidjah.ch/) to provide fast, -detailed, and context-aware autocompletion. - -![](/static/images/docs/language-python-autocomplete.png) - -By default, Nuclide will provide tab-able snippets for function and method -arguments. To turn this behavior on or off: - -1. Open the [Nuclide Settings](/docs/editor/basics/#preferences-pane) tab either by pressing `Cmd+,` (`Ctrl-,` on Linux) or by going to `Package | Settings View | Open`. -2. Select **Packages** from the list at the left, and search for `nuclide`. -3. Click on the **Settings** button for the `nuclide` package. -4. Scroll down until you find `nuclide-python`, and select or deselect the **Autocomplete arguments** checkbox. - -### Jump to Definition - -Nuclide allows you to directly jump to definition for local or imported symbols -alike. - -For example, to go to the definition of `get_all_patches()`, you can -hover over `get_all_patches()`and either press `Cmd-` -(`Ctrl-` on Linux) or `Cmd-Option-Enter` (`Ctrl-Alt-Enter` on Linux). - -![](/static/images/docs/language-python-jump-to-definition-link.png) - -![](/static/images/docs/language-python-jump-to-definition-result.png) - -Jump to definition also works for [Buck](http://buckbuild.com) config files. -Since `BUCK` files are written in Python, you can use `Cmd-` -(`Ctrl- Nuclide's built-in Swift support is not endorsed by Apple. The Swift - logo is a registered trademark of Apple Inc. - -
- -* TOC -{:toc} - -## Configuring Nuclide for Swift Package Development - -Nuclide will attempt to find a Swift executable automatically: - -- On macOS, it will use the latest version of Swift installed at `/Library/Developer/Toolchains/swift-latest.xctoolchain`. -- On Linux, it will find a Swift executable based on your `$PATH`. - -You may use a specific version of Swift by setting the **Swift Toolchain Path** in the Nuclide settings: - -1. Open the [Nuclide Settings](/docs/editor/basics/#preferences-pane) tab either by pressing `Cmd+,` (`Ctrl-,` on Linux) or by going to `Package | Settings View | Open`. -2. Select **Packages** from the list at the left, and search for `nuclide`. -3. Click on the **Settings** button for the `nuclide` package. -4. Scroll down until you find `nuclide-swift`, and enter the Toolchain path in the **Swift Toolchain Path** text box. - -![](/static/images/docs/language-swift-toolchain-path-setting.png) - -Nuclide uses [SourceKitten](https://github.com/jpsim/SourceKitten) to provide features such as [Autocomplete]((#features__autocomplete)). - -On macOS, Nuclide expects to find a SourceKitten executable at `/usr/local/bin/sourcekitten`. Installing SourceKitten via [Homebrew](http://brew.sh/), by running `brew install sourcekitten` at the command line, places it in this location. - -> Unfortunately, SourceKitten is not yet available on Linux. As a result, - features such as [Autocomplete](#features__autocomplete) are only available on macOS. - -You may configure Nuclide to use a SourceKitten executable at a different location by setting the **Path to SourceKitten Executable** in the Nuclide -settings. - -1. Open the [Nuclide Settings](/docs/editor/basics/#preferences-pane) tab either by pressing `Cmd+,` (`Ctrl-,` on Linux) or by going to `Package | Settings View | Open`. -2. Select **Packages** from the list at the left, and search for `nuclide`. -3. Click on the **Settings** button for the `nuclide` package. -4. Scroll down until you find `nuclide-swift`, and enter the custom SourceKitten path in the **Path to SourceKitten Executable** text box. - -## Features - -Swift integration in Nuclide provides you with productivity features such as: - -- [Building and Testing Swift packages](#features__building-and-testing-swift-packages) -- [Autocomplete](#features__autocomplete) - -### Building and Testing Swift packages - -The [Task Runner toolbar](/docs/features/task-runner) is used to build and test Swift packages. To open the Task Runner toolbar, click on the **Toggle Task Runner Toolbar** button in the [Nuclide toolbar](/docs/features/toolbar/#buttons) or search for `Nuclide Task Runner: Toggle Swift Toolbar` in the [Command Palette](/docs/editor/basics/#command-palette). - -See the [Task Runner Swift guide](/docs/features/task-runner/#swift) for how to build and test Swift packages. - -### Autocomplete - -Once you have [built your Swift package](#features__building-a-swift-package) via the [Task Runner's](/docs/features/task-runner) [Swift toolbar](/docs/features/task-runner/#swift), Nuclide will be able to provide autocompletion suggestions for Swift source code. - -![](/static/images/docs/language-swift-autocompletion.png) diff --git a/docs/_docs/platforms/android.md b/docs/_docs/platforms/android.md deleted file mode 100644 index 3f4fb406bf..0000000000 --- a/docs/_docs/platforms/android.md +++ /dev/null @@ -1,47 +0,0 @@ ---- -pageid: platform-android -title: Android -layout: docs -permalink: /docs/platforms/android/ ---- - -Nuclide's support for Android is currently much more basic and limited than that for -[iOS](/docs/platforms/ios). If you are a [React Native](/docs/platforms/react-native) developer for Android, there is more -full-featured support for the [Flow](/docs/languages/flow) or [JavaScript](/docs/languages/other/#javascript) side of your application. For debugging, there is -currently built-in support for [ADB logs](#emulator-logs). - -> This section discusses primarily native Android development since there is a whole separate -> section dedicated to [React Native](/docs/platforms/react-native). - -
- -* TOC -{:toc} - -## Features - -When you open an Android Java file (i.e., `.java`), you only get the basic syntax highlighting and -quick-completion capabilities given to you by Atom. - -## Running Applications - -Currently, the easiest way to build and run a native Android application is from an IDE such as -Android Studio. You can also use the command-line tools such as `adb`, `am`, etc. - -## Debugging - -Debugging Android applications is currently not supported except through the logs provided -by Nuclide's [Android Debug Bridge (ADB) Logcat support](#emulator-logs). - -## Emulator Logs - -When running your Android project in the Android emulator, you can open and view the emulator logs -directly within Nuclide. From the [Command Palette](/docs/editor/basics/#command-palette), search -for `Nuclide Adb Logcat: Start`. - -![](/static/images/docs/platform-android-toggle-simulator.png) - -![](/static/images/docs/platform-android-simulator-output.png) - -> Currently, the logs are very verbose as they do not delineate between actual underlying emulator -> information with the actual running application. diff --git a/docs/_docs/platforms/ios.md b/docs/_docs/platforms/ios.md deleted file mode 100644 index 8580e0b5b1..0000000000 --- a/docs/_docs/platforms/ios.md +++ /dev/null @@ -1,60 +0,0 @@ ---- -pageid: platform-ios -title: iOS -layout: docs -permalink: /docs/platforms/ios/ ---- - -Nuclide supports both native iOS development in [Objective-C](/docs/languages/objective-c) and -cross-platform development in [React Native](/docs/platforms/react-native). - -> This section discusses primarily native iOS development since there is a whole separate section -> dedicated to [React Native](/docs/platforms/react-native). - -
- -* TOC -{:toc} - -## Features - -When you open an [Objective-C](/docs/languages/objective-c/) file (e.g., `.h`, `.m`, `.mm`), you -automatically get support for default [features](/docs/languages/objective-c/#default-features) such -as [Automatic Square Bracket Completion](/docs/languages/objective-c/#default-features__automatic-square-bracket-completion). - -However, if you compile your project with [Buck](http://buckbuild.com), you get richer -[features](/docs/languages/objective-c/#buck-enabled-features) such as -[Autocomplete](/docs/languages/objective-c/#buck-enabled-features__autocomplete) and -[Jump to Definition](/docs/languages/objective-c/#buck-enabled-features__jump-to-definition). - -![](/static/images/docs/platform-ios-native-autocomplete.png) - -## Running Applications - -Currently, the easiest way to build and run a native iOS application is from Xcode itself. -You can also use the command-line tools such as `xcodebuild`, etc. - -### Buck Integration - -Nuclide supports the [Buck](https://buckbuild.com/) build system. See the -[Buck guide](/docs/features/buck) for how to build, run, and debug iOS apps. - -## Debugging - -Debugging native [Objective-C](/docs/languages/objective-c/) iOS applications is -[supported using Buck](/docs/features/buck/#debug). - -> [React Native](/docs/platforms/react-native/#debugging) is also supported. - -## Simulator Logs - -When running your iOS project in the iOS simulator, you can open and view the simulator logs -directly within Nuclide. From the [Command Palette](/docs/editor/basics/#command-palette), search -for `Nuclide iOS Simulator Logs: Start`. - -![](/static/images/docs/platform-ios-toggle-simulator.png) - -![](/static/images/docs/platform-ios-simulator-output.png) - -> Currently, the logs are very verbose as they do not delineate between actual underlying simulator -> information with the actual running application. diff --git a/docs/_docs/platforms/react-native.md b/docs/_docs/platforms/react-native.md deleted file mode 100644 index 697ed74f9c..0000000000 --- a/docs/_docs/platforms/react-native.md +++ /dev/null @@ -1,145 +0,0 @@ ---- -pageid: platform-react-native -title: React Native -layout: docs -permalink: /docs/platforms/react-native/ ---- - -Nuclide has built-in support for the [React Native](https://facebook.github.io/react-native/) -framework. React Native provides a set of components and extensions that allows you to easily write -native iOS and Android applications using the [Flow](/docs/languages/flow) and -[JavaScript](/docs/languages/other#javascript) programming languages and the -[React](http://facebook.github.io/react/) UI library. - -* TOC -{:toc} - -## Features - -If your React Native apps are primarily written in [Flow](/docs/languages/flow), you get all of its -[features](/docs/languages/flow/#features) within Nuclide, including -[Autocomplete](/docs/languages/flow/#autocomplete), -[Code Diagnostics](/docs/languages/flow/#features__code-diagnostics), etc. - -![](/static/images/docs/platform-react-native-feature-autocomplete.png) - -> [JavaScript](/docs/languages/other/#javascript) works well with Nuclide as well. - -> You can also write [native iOS (Objective-C)](/docs/platforms/ios) code with React Native, and get -> features such as [Automatic Square Bracket Completion](/docs/languages/objective-c/#default-features__automatic-square-bracket-completion) from Nuclide when doing so. Native Android code written in conjunction with React Native has [minimal support](/docs/platforms/android). - -## Running applications - -All React Native features are currently available from the [Command Palette](/docs/editor/basics/#command-palette). - -![](/static/images/docs/platform-react-native-debugging-command-palette.png) - -You run the React Native Packager and Server from Nuclide and your application from the command line. - -### React Native Packager - -From the [Command Palette](/docs/editor/basics/#command-palette), choose `Nuclide React Native: Start Packager` to start the React Native Server. The output in the [Console](/docs/features/debugger/#basics__evaluation) panel indicates if the React Native Packager started or if it encountered any errors. - -![](/static/images/docs/platform-react-native-start-packager.png) - -The server runs on the default `port 8081`. You can stop and restart the server at anytime. - -### Command Line - -Ensure that you are in the root directory of the React Native project, then run the application from the command-line: - -```bash -$ react-native run-ios -$ react-native run-android -``` - -This should bring up the Simulator with your running application inside. - -## Debugging - -[React Native](https://facebook.github.io/react-native/) for [iOS](/docs/platforms/ios) has -first-class support within Nuclide. The Debugger is no exception. - -> Debugging React Native for Android is currently not supported except for the -> [Simulator logs](#simulator-logs). - -From Nuclide, you can start a React Native development server, inspect React Native elements and -use the [Debugger](/docs/features/debugger#basics) to set and stop on breakpoints, etc. - -> In order to use React Native within Nuclide, you must -> [install](https://facebook.github.io/react-native/docs/getting-started.html) it. - -### Loading a React Native Project - -You open a React Native project the -[usual way](/docs/quick-start/getting-started/#adding-a-project). Nuclide will automatically -establish that you have a React Native project by seeing the `node_modules/react-native` directory -from the root of your project. - -### React Native Server - -Before starting the Debugger, [launch the React Native Server from within Nuclide](#running-applications__react-native-packager). - -### Prime the Debugger - -After starting the server, you can prime the React Native Debugger for when the application begins -running. From the [Command Palette](/docs/editor/basics/#command-palette), launch -`Nuclide React Native: Start Debugging`. - -You might see that the Nuclide Debugger UI appears but doesn't start, instead showing you a waiting condition. - - - -This means that the Debugger is waiting to attach to the actual running process of the React -Native application. - -### Run the React Native Application - -[Start your React Native application from the command-line](#running-applications__command-line). - -### Enable Debugging from the Application - -From the Simulator, you will want to enable debugging the application. Press `Cmd-D` (`Ctrl-D` on -Linux). This will bring up the debug options for your application. Select **Debug JS Remotely**. - -![](/static/images/docs/platform-react-native-debug-options.png) - -> If you have enabled debugging in a previous session, then debugging will still be enabled; thus, -> this step will not be necessary. - -### Start Debugging - -After you enable debugging from the simulated application, Nuclide will attach to that debugging -process automatically, since we primed the Debugger above. You can now set breakpoints, Watch Expressions, -etc. - -> You can set breakpoints, Watch Expressions, etc. earlier than this step, but access to them will not be -> available until the debugging has been enabled. - -> If the Debugger is paused when it opens, you may have to click the resume execution button -> (i.e., the play icon) for debugging to begin. - -Now you can start debugging your React Native application as [normal](/docs/features/debugger#basics). - -![](/static/images/docs/platform-react-native-debugging.png) - -### Element Inspector - -The React Native Debugger in Nuclide also provides an Element Inspector, where you can view and -toggle properties of your application. - -From the [Command Palette](/docs/editor/basics/#command-palette), choose `Nuclide React Native Inspector: Show` to open the **React Native Inspector** tab in the -main [Editing Area](/docs/editor/basics/#editing-area). - -![](/static/images/docs/platform-react-native-element-inspector.png) - -To see the actual elements highlighted in the Nuclide Element Inspector also highlighted in the -Simulator, you must enable the Simulator Inspector as well. Press `Cmd-D` (`Ctrl-D` on Linux) within -the Simulator and choose **Show Inspector**. - -![](/static/images/docs/platform-react-native-show-inspector.png) - -## Simulator Logs - -Nuclide supports the [iOS Simulator logs](/docs/platforms/ios#simulator-logs) and -[Android Emulator logs](/docs/platforms/android#emulator-logs) directly within Nuclide. diff --git a/docs/_docs/platforms/web.md b/docs/_docs/platforms/web.md deleted file mode 100644 index 353e4e5d2b..0000000000 --- a/docs/_docs/platforms/web.md +++ /dev/null @@ -1,41 +0,0 @@ ---- -pageid: platform-web -title: Web Development -layout: docs -permalink: /docs/platforms/web/ ---- - -The development of modern websites makes use of both server-side and client-side web technologies. -Nuclide makes web developers more productive in this process. - -* TOC -{:toc} - -## Server-side Development - -[Hack](/docs/languages/hack) has first-class support in Nuclide. In conjunction with -[HHVM](http://docs.hhvm.com), Hack offers quick development and testing with the comfort of -[type safety](https://docs.hhvm.com/hack/typechecker/introduction). Nuclide enhances this by -utilizing Hack's information to deliver developer productivity features such as -[Autocomplete](/docs/languages/hack/#features__autocomplete) and -[inline error checking](/docs/languages/hack/#features__code-diagnostics). - -If you are a [PHP](http://php.net) developer, Nuclide has [support](/docs/languages/other/#php) for that as well. - -## Client-side Development - -[Flow](/docs/languages/flow) has first-class support in Nuclide. Flow gives you -[type safety](http://flowtype.org) as you develop, and Nuclide uses the information provided by -Flow to enhance developer productivity. This includes -[Jump to Definition](/docs/languages/flow/#jump-to-definition) and -[Type Hinting](/docs/languages/flow/#type-hinting). - -If you are a [JavaScript](https://developer.mozilla.org/en-US/docs/Web/JavaScript) developer, -Nuclide has [support](/docs/languages/other/#javascript) for that as well. - -## Scripting - -Nuclide supports many languages to help you write your scripts quicker and error-free. With -first-class support for [Hack](/docs/languages/hack) and [Flow](/docs/languages/flow), along -with support for [C++](/docs/languages/cpp), Nuclide make you more productive in your script -writing. diff --git a/docs/_docs/quick-start/getting-started.md b/docs/_docs/quick-start/getting-started.md deleted file mode 100644 index 8d4a8c22d8..0000000000 --- a/docs/_docs/quick-start/getting-started.md +++ /dev/null @@ -1,128 +0,0 @@ ---- -pageid: quick-start-getting-started -title: Getting Started -layout: docs -permalink: /docs/quick-start/getting-started/ ---- - -This getting started guide walks you through the core features of Nuclide and aims to get you productive quickly. See [Basics](/docs/editor/basics) for more information on using Nuclide's editing features. - -* TOC -{:toc} - -## Installation - -The [installation guides](/docs/editor/setup/) provide detailed information to install -Nuclide on your platform, but if you have already met the platform dependent prerequisites -([macOS](/docs/editor/setup/#macos__prerequisites) | [Linux](/docs/editor/setup/#linux__prerequisites)), -you can install Nuclide easily from within Atom itself. - -> Nuclide can be installed on [Windows](#windows), but it is [not fully supported](https://github.com/facebook/nuclide/issues/321). - -
- -1. Open Atom. -2. Choose `Atom | Preferences` (`Edit | Preferences` on Linux and `File | Settings` on Windows) to bring up the **Settings** tab. -3. In the **Settings** tab, select **Install** from the list at the left. -4. In the search box, type "Nuclide" and press the `Enter` key. -5. Click the **Install** button for the `nuclide` package. - -![](/static/images/docs/editor-setup-atom-install-nuclide.png) - -> Installing Nuclide within the Atom Packages UI is the recommended method, however you can install Nuclide from the command-line, if you wish, using: -> -```bash -$ apm install nuclide -``` -> - -
- -### Packages - -If you want features such as [Quick Open](#quick-open), [Remote Development](/docs/features/remote), and [Mercurial support](/docs/features/hg) to work correctly, you also need to install [Watchman](https://facebook.github.io/watchman/) and ensure it is in your `$PATH` environment variable. There are other [recommended package installations](/docs/editor/setup/#post-installation) as well. - -## Launch - -After installation, launch Nuclide by [opening Atom](/docs/editor/basics/#opening). Once Atom -is open, you should see the Nuclide Home page. - -![](/static/images/docs/quick-start-getting-started-home.png) - -- The left side-pane is the Nuclide [Project Explorer](/docs/editor/basics/#project-explorer). -- The main pane contains introductory information about Nuclide and the Quick Launch Menu. This is also where you will edit your files (just like in normal Atom). -- The bottom status bar shows you error and health statistics. - -## Adding a Project - -The first common step after launching Nuclide is to open a project you would like to work on. -This could be a [Hack](/docs/languages/hack/), [Flow](/docs/languages/flow/), or any other project that has a root directory. - -To add a project, click the **Add Project Folder** button in the left side-pane, use the `Cmd-Shift-O` keyboard shortcut (`Ctrl-Shift-O` on Linux), or choose -`File | Add Project Folder` from the Atom menu bar. - -![](/static/images/docs/quick-start-getting-started-add-project.png) - -After adding a project you will see the root of your project at the top of the [Project Explorer's](/docs/editor/basics/#project-explorer) File Tree with all -files and folders as a tree hierarchy underneath it. - -![](/static/images/docs/quick-start-getting-started-file-tree-view.png) - -## Quick Launch Menu - -On the Nuclide Home page you will find the Quick Launch Menu that gives quick access to many of -the popular features of Nuclide. Click the **Try It** button of any feature to use it. - -![](/static/images/docs/quick-start-getting-started-quick-launch-menu.png) - -## Quick Open - -The [Quick Open](/docs/features/quick-open) feature gives you access to Nuclide's file -search mechanism, including [OmniSearch](/docs/features/quick-open/#omnisearch), which quickly displays recently opened files, quick searches for files based on partial names, and depending on the project, can search within files for symbols, etc. Click **Try It** or use the `Cmd-T` keyboard shortcut (`Ctrl-T` on Linux) to access the feature. - -![](/static/images/docs/quick-start-getting-started-quick-open.png) - -You can also search by filenames in your project, filenames of currently open files, and see which files have been -recently opened. - -## Remote Connection - -Nuclide provides the ability to do [remote development](/docs/features/remote/) out of the box. This -allows you to have Nuclide installed on a local machine, your project on a remote machine, and have -your editing experience be seamless between the two. - -Nuclide provides a *server* that bridges your local client with the remote development machine. In -order for remote development to work correctly, you must meet the -[prerequisites](/docs/features/remote/#nuclide-server__prerequisites) on the remote machine before -installing the Nuclide server. - -Once the prerequisites are met, you can -[install the server](/docs/features/remote/#nuclide-server__setup) on the remote machine. - -In order to connect to your remote project, click on the **Try It** button next to -**Remote Connection** in the Quick Launch Menu. You can also select `Nuclide | Remote Projects | Connect to Remote Project...`, -use the `Ctrl-Shift-Cmd-C` keyboard shortcut, or click **Add Remote Project Folder** -in the [Project Explorer](/docs/editor/basics/#project-explorer) (however, please note that if you have other projects open that button will not be there). - -![](/static/images/docs/quick-start-getting-started-remote-connection-dialog.png) - -Enter all the necessary credentials, including the username for logging into the remote server, the -server's address, and the actual root directory of the remote project you want to open. Then, if you installed the Nuclide Server as instructed, the **Remote Server Command** is -`nuclide-start-server`. - -Any changes you make in the local Nuclide editor will be communicated back to the remote server and -properly synchronized. - -## Diff View - -Nuclide has built-in support for [Mercurial-based repositories](/docs/features/hg). If your -project is using Mercurial, one of the features that may help your workflow is the -[Diff View](/docs/features/hg/#diff-view). This allows you to quickly see what has changed in the -files you have modified. It shows what has changed from the current committed revision which you -are tracking. - -To access the Diff View, click the **Try It** button, use the `Alt-Cmd-Shift-D` keyboard shortcut, or select `Nuclide | Source Control | Toggle Diff View` after making a change to one of the files in your Mercurial project. - -![](/static/images/docs/quick-start-getting-started-diff-view.png) - -When the **Diff View** tab appears, click on a changed file in the right pane to have the Diff View window highlight any changes. diff --git a/docs/_includes/blog_pagination.html b/docs/_includes/blog_pagination.html deleted file mode 100644 index e26da279bc..0000000000 --- a/docs/_includes/blog_pagination.html +++ /dev/null @@ -1,28 +0,0 @@ - -{% if paginator.total_pages > 1 %} -
- -
-{% endif %} diff --git a/docs/_includes/content/gridblocks.html b/docs/_includes/content/gridblocks.html deleted file mode 100644 index 7bdca6ef88..0000000000 --- a/docs/_includes/content/gridblocks.html +++ /dev/null @@ -1,6 +0,0 @@ -
-{% for item in {{include.data_source}} %} - {% include content/items/gridblock.html item=item gridtype=include.grid_type %} - {% cycle '', '
' %} -{% endfor %} -
\ No newline at end of file diff --git a/docs/_includes/content/items/gridblock.html b/docs/_includes/content/items/gridblock.html deleted file mode 100644 index d79b5f868f..0000000000 --- a/docs/_includes/content/items/gridblock.html +++ /dev/null @@ -1,7 +0,0 @@ -
- {% if item.image %} - {{ item.title }} - {% endif %} -

{{ item.title }}

- {{ item.text | markdownify }} -
diff --git a/docs/_includes/doc.html b/docs/_includes/doc.html deleted file mode 100644 index ec63dd5cb8..0000000000 --- a/docs/_includes/doc.html +++ /dev/null @@ -1,23 +0,0 @@ -
-
-

{% if include.truncate %}{{ page.title }}{% else %}{{ page.title }}{% endif %}

-
- -
- {% if include.truncate %} - {% if page.content contains '' %} - {{ page.content | split:'' | first }} - - {% else %} - {{ page.content }} - {% endif %} - {% else %} - {{ content }} - {% endif %} -
- {% include doc_paging.html %} -
diff --git a/docs/_includes/doc_paging.html b/docs/_includes/doc_paging.html deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/docs/_includes/footer.html b/docs/_includes/footer.html deleted file mode 100644 index 3943a3d516..0000000000 --- a/docs/_includes/footer.html +++ /dev/null @@ -1,24 +0,0 @@ -
- -
- - - -{% comment %} -For Algolia search -{% endcomment %} - - - diff --git a/docs/_includes/head.html b/docs/_includes/head.html deleted file mode 100644 index eeb9bbe0b1..0000000000 --- a/docs/_includes/head.html +++ /dev/null @@ -1,33 +0,0 @@ - - - - - - {% seo %} - - {% comment %} - For Algolia search - {% endcomment %} - - - {% comment %}Local "Gotham Rounded A" stylesheet{% endcomment %} - - - - - {% comment %} - The file below is the redirect destination of 'http://fb.me/react-with-addons-0.13.1.min.js'. Use - the final destination to eliminate a redirect for clients. - {% endcomment %} - - - {% comment %} - jQuery and ajax to automatically insert Atom and Node version dependencies into the documentation. - {% endcomment %} - - {% comment %} - For our RSS feed.xml - https://help.github.com/articles/atom-rss-feeds-for-github-pages/ - {% endcomment %} - {% feed_meta %} - diff --git a/docs/_includes/hero.html b/docs/_includes/hero.html deleted file mode 100644 index c7423f75ef..0000000000 --- a/docs/_includes/hero.html +++ /dev/null @@ -1,9 +0,0 @@ -
-
-
-

An image management library

- -
-
diff --git a/docs/_includes/homeContent.html b/docs/_includes/homeContent.html deleted file mode 100644 index 44fbd4dfb4..0000000000 --- a/docs/_includes/homeContent.html +++ /dev/null @@ -1,16 +0,0 @@ -
-
-
-

{{ site.tagline }}

-
-

{% if page.excerpt %}{{ page.excerpt | strip_html }}{% else %}{{ site.description }}{% endif %}

-
-
- Get Started or read more about using Nuclide for React Native, iOS, or Web development. -
-
- -
-
diff --git a/docs/_includes/nav.html b/docs/_includes/nav.html deleted file mode 100644 index dee708140b..0000000000 --- a/docs/_includes/nav.html +++ /dev/null @@ -1,108 +0,0 @@ -
-
- - -

{{ site.title }}

-
- - -
- - -
diff --git a/docs/_includes/nav_blog.html b/docs/_includes/nav_blog.html deleted file mode 100644 index ebbb173898..0000000000 --- a/docs/_includes/nav_blog.html +++ /dev/null @@ -1,85 +0,0 @@ - - - diff --git a/docs/_includes/nav_docs.html b/docs/_includes/nav_docs.html deleted file mode 100644 index 2fd641921f..0000000000 --- a/docs/_includes/nav_docs.html +++ /dev/null @@ -1,98 +0,0 @@ - - - diff --git a/docs/_includes/plugins/all_share.html b/docs/_includes/plugins/all_share.html deleted file mode 100644 index a62015b685..0000000000 --- a/docs/_includes/plugins/all_share.html +++ /dev/null @@ -1,3 +0,0 @@ -
- {% include plugins/like_button.html %} -
diff --git a/docs/_includes/plugins/button.html b/docs/_includes/plugins/button.html deleted file mode 100644 index 0f54034ee2..0000000000 --- a/docs/_includes/plugins/button.html +++ /dev/null @@ -1 +0,0 @@ -{{ include.button_text }} \ No newline at end of file diff --git a/docs/_includes/plugins/group_join.html b/docs/_includes/plugins/group_join.html deleted file mode 100644 index da4ca649a6..0000000000 --- a/docs/_includes/plugins/group_join.html +++ /dev/null @@ -1 +0,0 @@ -{{ include.button_text }} \ No newline at end of file diff --git a/docs/_includes/plugins/like_button.html b/docs/_includes/plugins/like_button.html deleted file mode 100644 index 2ae5ff28da..0000000000 --- a/docs/_includes/plugins/like_button.html +++ /dev/null @@ -1,18 +0,0 @@ -
- \ No newline at end of file diff --git a/docs/_includes/plugins/post_social_plugins.html b/docs/_includes/plugins/post_social_plugins.html deleted file mode 100644 index cb4d6e2ece..0000000000 --- a/docs/_includes/plugins/post_social_plugins.html +++ /dev/null @@ -1,34 +0,0 @@ -
- -
-
- - - diff --git a/docs/_includes/plugins/slideshow.html b/docs/_includes/plugins/slideshow.html deleted file mode 100644 index ae692752b5..0000000000 --- a/docs/_includes/plugins/slideshow.html +++ /dev/null @@ -1,87 +0,0 @@ -
- - \ No newline at end of file diff --git a/docs/_includes/post.html b/docs/_includes/post.html deleted file mode 100644 index 26a37c58ef..0000000000 --- a/docs/_includes/post.html +++ /dev/null @@ -1,22 +0,0 @@ -
- {% assign author = site.data.authors[include.post.author] %} -
- {% if author.fbid %} -
- {{ author.fullname }} -
- {% endif %} - {% if author.full_name %} - - {% endif %} -

{% if include.truncate %}{{ include.post.title }}{% else %}{{ include.post.title }}{% endif %}

- -
- -
- {{ include.post.content | markdownify }} - {% unless include.truncate %} - {% include plugins/all_share.html %} - {% endunless %} -
-
diff --git a/docs/_includes/social_plugins.html b/docs/_includes/social_plugins.html deleted file mode 100644 index 6c6af4ac5e..0000000000 --- a/docs/_includes/social_plugins.html +++ /dev/null @@ -1,24 +0,0 @@ - -
- -
- - - diff --git a/docs/_includes/ui/button.html b/docs/_includes/ui/button.html deleted file mode 100644 index 729ccc33b9..0000000000 --- a/docs/_includes/ui/button.html +++ /dev/null @@ -1 +0,0 @@ -{{ include.button_text }} \ No newline at end of file diff --git a/docs/_layouts/blog.html b/docs/_layouts/blog.html deleted file mode 100644 index c070a1fa44..0000000000 --- a/docs/_layouts/blog.html +++ /dev/null @@ -1,12 +0,0 @@ ---- -category: blog -layout: default ---- - -
-
- {% include nav_blog.html %} - {{ content }} -
-
- diff --git a/docs/_layouts/default.html b/docs/_layouts/default.html deleted file mode 100644 index ad2681b6b2..0000000000 --- a/docs/_layouts/default.html +++ /dev/null @@ -1,10 +0,0 @@ - - - {% include head.html %} - - {% include nav.html alwayson=true %} - {{ content }} - {% include footer.html %} - - - diff --git a/docs/_layouts/doc_page.html b/docs/_layouts/doc_page.html deleted file mode 100644 index 79bc7fcc97..0000000000 --- a/docs/_layouts/doc_page.html +++ /dev/null @@ -1,11 +0,0 @@ ---- -layout: default ---- - -
-
- {% include nav_docs.html %} - {{ content }} -
-
- diff --git a/docs/_layouts/docs.html b/docs/_layouts/docs.html deleted file mode 100644 index 749dafabbe..0000000000 --- a/docs/_layouts/docs.html +++ /dev/null @@ -1,5 +0,0 @@ ---- -layout: doc_page ---- - -{% include doc.html %} \ No newline at end of file diff --git a/docs/_layouts/home.html b/docs/_layouts/home.html deleted file mode 100644 index e3595df98b..0000000000 --- a/docs/_layouts/home.html +++ /dev/null @@ -1,14 +0,0 @@ - - - {% include head.html %} - - {% include nav.html alwayson=true %} - {% include homeContent.html %} -
-
- {{ content }} -
-
- {% include footer.html %} - - diff --git a/docs/_layouts/page.html b/docs/_layouts/page.html deleted file mode 100644 index b27134d134..0000000000 --- a/docs/_layouts/page.html +++ /dev/null @@ -1,10 +0,0 @@ ---- -layout: default ---- -
-
- {% include nav_blog.html %} - {{ content }} -
-
- diff --git a/docs/_layouts/plain.html b/docs/_layouts/plain.html deleted file mode 100644 index fccc02ce17..0000000000 --- a/docs/_layouts/plain.html +++ /dev/null @@ -1,10 +0,0 @@ ---- -layout: default ---- - -
-
- {{ content }} -
-
- diff --git a/docs/_layouts/post.html b/docs/_layouts/post.html deleted file mode 100644 index d361eb981f..0000000000 --- a/docs/_layouts/post.html +++ /dev/null @@ -1,6 +0,0 @@ ---- -collection: blog -layout: page ---- - -{% include post.html post=page %} diff --git a/docs/_layouts/redirect.html b/docs/_layouts/redirect.html deleted file mode 100644 index c24f817484..0000000000 --- a/docs/_layouts/redirect.html +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/docs/_layouts/top-level.html b/docs/_layouts/top-level.html deleted file mode 100644 index fccc02ce17..0000000000 --- a/docs/_layouts/top-level.html +++ /dev/null @@ -1,10 +0,0 @@ ---- -layout: default ---- - -
-
- {{ content }} -
-
- diff --git a/docs/_posts/2016-01-13-Nuclide-v0.111.0-The-Unified-Package.md b/docs/_posts/2016-01-13-Nuclide-v0.111.0-The-Unified-Package.md deleted file mode 100644 index 8534f4083b..0000000000 --- a/docs/_posts/2016-01-13-Nuclide-v0.111.0-The-Unified-Package.md +++ /dev/null @@ -1,106 +0,0 @@ ---- -layout: post -title: "Nuclide v0.111.0: The Unified Package" -author: zertosh ---- - -This is a significant release for Nuclide that is mainly aimed at improving and simplifying Nuclide as an open source project. The most apparent and important change is moving Nuclide from many Atom -packages—44 of them to be exact—to just one: `nuclide`. We will discuss below why we are excited -about moving to a single package and how it improves Nuclide for everyone, but first we will cover -how to get going with the new release. - -## Installing Nuclide v0.111.0 - -Nuclide v0.111.0 is a single Atom package. To install it, you can either search for the -['nuclide' Atom package](https://atom.io/packages/nuclide) in *Atom > Packages > Install* or install -it from the command line with `apm`. While this release focuses on moving to a single package, it -does include fixes and improvements that you can find in the -[CHANGELOG.md](https://github.com/facebook/nuclide/blob/v0.111.0/CHANGELOG.md). - -```bash -$ apm install nuclide -``` - -#### Installing Nuclide Server v0.111.0 - -Nuclide's server has moved into the ['nuclide' NPM package](https://www.npmjs.com/package/nuclide). -The server is required only if you intend to edit remote files from within Atom+Nuclide, and it -should be installed on the host where the remote files live. We recommend installing the server as -a global module using NPM's `-g` flag so its binaries are available in '/usr/local/bin'. - -```bash -$ npm install -g nuclide -``` - -### New Version Scheme - -The last version of the Nuclide packages that were published was v0.0.35. Internally, however, the -server was last released as v0.108.0. This release adopts our internal version scheme so the -versions stay in sync with open source releases. - -### Migrating from Previous Versions - -If you previously installed Nuclide via the `nuclide-installer` package or by installing `nuclide-` -packages individually, you should uninstall them first. Follow the -[v0.0.35 uninstall instructions](/docs/editor/uninstall/#v0-0-35-and-prior) to ensure previous -versions of Nuclide are removed. - -The new 'nuclide' package will automatically disable any deprecated 'nuclide-*' packages and warn -you on start up that you should uninstall them to ensure everything works as expected. - -## Configuring Single-package Nuclide - -Because Nuclide is now a single Atom Package, its settings are unified under the 'nuclide' package -in *Atom > Packages > nuclide > Settings*. - -![](/static/images/blog/nuclide-atom-settings.png) - -Features you may have been familiar with as separate packages before, such as Hyperclick, -Diagnostics, and File Tree, are now listed as features in Nuclide's Settings page and are togglable -as if they were Atom packages. If you want to use only one or a few of the features of Nuclide, you -can disable the rest of Nuclide without incurring any load time for the disabled features' code. All -features are enabled by default. - -![](/static/images/blog/nuclide-feature-settings.png) - -### Migrating Settings from Previous Packages - -If you changed settings in any of Nuclide's previous packages, the settings will be automatically -migrated to their new location in the `nuclide.` namespace when you first launch Atom after -installing the 'nuclide' package. The settings will be configurable like before but under the -*Atom > Packages > nuclide > Settings* rather than under the package's name. - -## Why a Single Atom Package? - -The Atom ecosystem is centered around modular packages that can be installed and updated -independently, and Nuclide took that same approach from the start. We wrote scripts to let our code -live in a single repository but be released as many Atom packages. Nuclide releases were actually -simultaneous releases of 40+ Atom packages. While this fit well with the Atom model, it meant we -also had to distribute a "installer" package that oversaw the installation of top-level Atom -packages. - -In practice, the installer process was computationally expensive, difficult to -troubleshoot, and took roughly 40 minutes partially due to large amounts of network traffic. When -all Nuclide packages were installed, they filled over 3GB of disk space. Nuclide packages are -heavily interdependent, and because they were installed as top-level Atom packages they each had -their own 'node_modules' directory with largely duplicate dependencies. - -By unifying Nuclide into a single Atom package, we aimed to improve installation, updates, and -maintenance. The single 'nuclide' package does not require a special installer, only `apm install` -like other Atom packages. This simplifies installation for everyone and makes Nuclide updates fast. -Once installed, the 'nuclide' package takes under 110MB of disk space, a 95%+ reduction in disk use, -and subsequently, network use during installation. The dramatic drop in disk use was possible -because Nuclide's features now share a single 'node_modules' directory and use relative paths to -require one another, eliminating the duplicate dependencies present when Nuclide was 40+ top-level -Atom packages. - -## What's Next? - -We are excited to greatly improve the experience of Nuclide for users outside Facebook. This release -should solve many of the most common installation and upgrade issues that have been reported, and it -paves the way for more frequent and more stable releases. We hope that simplifying the installation -process will make [Nuclide's source](https://github.com/facebook/nuclide) more familiar to other -Atom developers and make it easier for anyone to contribute. - -If you run into issues with the upgrade process, or if you run into any issue at all, open a -[Nuclide GitHub issue](https://github.com/facebook/nuclide/issues) so we can help out. diff --git a/docs/_sass/_base.scss b/docs/_sass/_base.scss deleted file mode 100644 index d22f819849..0000000000 --- a/docs/_sass/_base.scss +++ /dev/null @@ -1,960 +0,0 @@ -body { - background: $footer-bg; - color: $text; - font: 300 #{$base-font-size}/#{$base-line-height} $base-font-family; - text-align: center; - text-rendering: optimizeLegibility; -} - -img { - max-width: 100%; -} - -article { - p { - img { - max-width: 100%; - display:block; - margin-left: auto; - margin-right: auto; - } - } -} - -a { - border-bottom: 1px dotted $primary-bg; - color: $text; - text-decoration: none; - -webkit-transition: background 0.3s, color 0.3s; - transition: background 0.3s, color 0.3s; -} - -blockquote { - padding: 15px 30px 15px 15px; - margin: 20px 0 0 10px; - background-color: rgba(204, 122, 111, 0.1); - border-left: 10px solid rgba(191, 87, 73, 0.2); -} - -#fb_oss a { - border: 0; -} - -h1, h2, h3, h4 { - font-family: $header-font-family; -} - -.headerBarContainer { - background: $primary-bg; - color: $header-text; - height: $header-height; - opacity: 0.0; - padding: $header-ptop 0 $header-pbot; - position: relative; - -webkit-transition: opacity 0.2s ease-in-out; - transition: opacity 0.2s ease-in-out; - width: 100%; - z-index: 9999; - - &.visible { - opacity: 1.0; - } - - a { - border: 0; - color: $header-text; - } - - header { - height: $header-height; - margin: 0 auto; - max-width: $content-width; - padding: 0 20px; - position: relative; - text-align: left; - - img { - height: 30px; - margin-right: 10px; - } - - h2 { - display: inline; - font-family: $header-font-family; - font-size: 16px; - letter-spacing: -0.02em; - line-height: 18px; - position: relative; - top: -9px; - } - } - - .navigationWrapper { - display: inline-block; - font-family: $header-font-family; - - &.navigationFull { - display: none; - } - - &.navigationSlider { - position:absolute; - right: 12px; - z-index:99; - - .navSlideout { - cursor: pointer; - font-size: 24px; - padding-top: 5px; - -webkit-transition: -webkit-transform 0.3s; - transition: transform 0.3s; - } - - .slidingNav { - background: #222; - box-sizing: border-box; - height: 100vh; - opacity: 0; - overflow: hidden; - padding: 0; - position: absolute; - right: -12px; - top: $header-height + $header-pbot; - -webkit-transition: opacity 0.5s, width 0.5s; - transition: opacity 0.5s, width 0.5s; - width: 0; - - &.slidingNavActive { - opacity: 1; - width: 75vw; - } - - ul { - list-style: none; - padding-left: 0; - - li { - padding: 0; - a { - border-bottom: 1px solid #111; - display:block; - padding: 4vw 12px; - -webkit-transition: background-color 0.3s; - transition: background-color 0.3s; - - &:focus, - &:hover { - background: $primary-bg; - } - } - } - } - } - } - } -} - -.homeContainer { - background: $primary-bg; - color: $header-text; - - a { - color: $header-text; - } - - .homeWrapper { - padding-bottom: 2em; - padding-top: 2em; - text-align: left; - - .wrapper { - margin: 0px auto; - max-width: $content-width; - padding: 0 20px; - } - - .projectLogo { - img { - height: 100px; - margin-bottom: 0px; - } - } - - h1#project_title { - font-family: $header-font-family; - font-size: 300%; - letter-spacing: -0.08em; - line-height: 1em; - margin-bottom: 80px; - } - - h2#project_tagline { - font-family: $header-font-family; - font-size: 200%; - letter-spacing: -0.04em; - line-height: 1em; - } - } -} - -.wrapper { - margin: 0px auto; - max-width: $content-width; - padding: 0 20px; -} - -.footerContainer { - background: $footer-bg; - - .footerWrapper { - padding-top: 4vh; - padding-bottom: 4vh; - } -} - - -.projectLogo { - display: none; - - img { - height: 100px; - margin-bottom: 0px; - } -} - -section#intro { - margin: 40px 0; -} - -.fbossFontLight { - font-family: $base-font-family; - font-weight: 300; - font-style: normal; -} - -.fb-like { - display: block; - margin-bottom: 50px; - width: 100%; -} - -a.blockButton { - background: $primary-bg; - border-radius: 4px; - border: 2px solid transparent; - clear: both; - color: $header-text; - display: inline-block; - font-family: $header-font-family; - font-size: 120%; - padding: 10px 20px; - position: relative; - -webkit-transition: background-color 0.2s, color 0.2s, border 0.2s; - transition: background-color 0.2s, color 0.2s, border 0.2s; - - .mainContainer .mainWrapper &:hover, - .mainContainer .mainWrapper &:focus { - background: $secondary-bg; - border: 2px solid $primary-bg; - color: $primary-bg; - } - - .homeContainer &{ - background: $light-color; - color: $light-text-color; - - &:hover, - &:focus { - background: $primary-bg; - border: 2px solid $light-color; - color: $light-text-color; - } - } -} - -.promoSection { - font-size: 125%; - line-height: 1.6em; - margin: 0; - position: relative; - z-index: 99; - - a { - border-bottom: 3px solid $light-color; - color: lighten($light-color, 20%); - } -} - -.center { - display: block; - text-align: center; -} - -.mainContainer { - background: $secondary-bg; - overflow: auto; - padding: 0 4vw; - - .mainWrapper { - padding-bottom: 4vh; - padding-top: 4vh; - text-align: left; - - .blockButton { - margin: 4vh 0; - - &.marginsmall { - margin: 1vh 0; - } - } - - .allShareBlock { - margin: -12px; - padding: 1vh 0; - - .pluginBlock { - margin: 12px; - padding: 0; - } - } - - a { - &:hover, - &:focus { - background: $primary-bg; - color: $header-text; - } - } - - em { - font-style: italic; - } - - strong, b { - font-weight: bold; - } - - h1 { - font-size: 300%; - line-height: 1em; - padding: 1.4em 0 1em; - text-align: center; - } - - h2 { - font-size: 250%; - line-height: 1em; - padding: 1.4em 0 1em; - text-align: left; - } - - h3 { - font-size: 150%; - line-height: 1em; - padding: 1em 0 0.8em; - } - - p { - padding: 0.8em 0; - } - - ol { - list-style: decimal; - } - - ul { - list-style: disc; - } - - ol, ul { - padding-left: 24px; - li { - padding-bottom: 4px; - padding-left: 6px; - } - } - - strong { - font-weight: bold; - } - - nav.toc { - position: relative; - section { - background: $primary-bg; - color: $header-text; - margin-bottom: 2vh; - padding: 12px 24px; - - .navGroup { - h3 { - display: none; - } - - &:not(.navGroupActive) { - display: none; - } - } - } - - .toggleNav { - position: relative; - } - - .navToggle { - background: $primary-bg; - color: $header-text; - font-size: 12px; - height: 24px; - position: absolute; - right: 0; - text-align: center; - top: 0; - width: 24px; - - i { - cursor: pointer; - } - } - - .toggleNavActive { - section { - .navGroup { - display: block; - - h3 { - display: block; - } - - ul li { - display: block; - } - } - - ul li { - display: block; - padding-bottom: 4px; - } - } - } - - h3 { - font-size: 125%; - padding-right: 24px; - padding-top: 0.4em; - } - - ul { - padding-left: 0; - padding-right: 24px; - - li { - list-style-type: none; - padding-bottom: 0; - padding-left: 0; - - &:not(.navListItemActive) { - display: none; - } - - a { - border-bottom: none; - border-left: 4px solid transparent; - color: $header-text; - display: inline-block; - margin-bottom: 0.6vh; - padding: 1vh 0 0.4vh 8px; - -webkit-transition: border-color 0.3s; - transition: border-color 0.3s; - - &:hover, - &:focus { - border-left: 4px solid $nav-text; - } - - &.navItemActive { - border-left: 4px solid $header-text; - } - } - } - } - } - - .post { - background: #fff; - padding: 6vw 6vw 8vh; - position: relative; - - a { - color: $link-color; - - &:hover, - &:focus { - color: #fff; - } - } - - h2 { - border-bottom: 4px solid $primary-bg; - font-size: 130%; - } - - h3 { - border-bottom: 1px solid $primary-bg; - font-size: 110%; - } - - .authorPhoto { - border-radius: 50%; - height: 50px; - left: 50%; - margin-left: -25px; - overflow: hidden; - position: absolute; - top: -25px; - width: 50px; - } - - .post-header { - padding: 0 0 1em; - text-align: center; - - h1 { - font-size: 150%; - line-height: 1em; - padding: 0.4em 0 0; - - a { - border: none; - } - } - - .post-authorName { - color: $primary-bg; - font-family: $header-font-family; - margin-top: -2vw; - text-align: center; - } - - .post-meta { - color: $primary-bg; - font-family: $header-font-family; - text-align: center; - } - } - - .postSocialPlugins { - padding-top: 1em; - } - - .docPagination { - background: $primary-bg; - bottom: 0px; - left: 0px; - position: absolute; - right: 0px; - - .pager { - display: inline-block; - width: 50%; - } - - .pagingNext { - float: right; - text-align: right; - } - - a { - border: none; - color: $header-text; - display: block; - padding: 4px 12px; - - &:hover { - background-color: $secondary-bg; - color: $text; - } - - .pagerLabel { - display: inline; - } - - .pagerTitle { - display: none; - } - } - } - } - - .posts { - .post { - margin-bottom: 6vh; - } - } - } -} - -.gridBlock { - margin: 20px 0; - padding: 2vh 0; - - .twoByGridBlock { - padding: 0; - - img { - margin-top: 6vh; - max-width: 100%; - } - - &.featureBlock h3 { - font-size: 150%; - margin: 20px 0; - padding-bottom: 0; - } - } - - .gridClear { - clear: both; - } - - .leftBlock { - padding: 40px 0; - text-align: left; - } -} - -#integrations_title { - font-size: 250%; - margin: 80px 0; -} - -.ytVideo { - height: 0; - overflow: hidden; - padding-bottom: 53.4%; /* 16:9 */ - padding-top: 25px; - position: relative; -} - -.ytVideo iframe, -.ytVideo object, -.ytVideo embed { - height: 100%; - left: 0; - position: absolute; - top: 0; - width: 100%; -} - -@media only screen and (min-width: 480px) { - h1#project_title { - font-size: 500%; - } - - h2#project_tagline { - font-size: 250%; - } - - .projectLogo { - img { - margin-bottom: 10px; - height: 200px; - } - } - - .headerBarContainer { - .navigationWrapper { - &.navigationSlider { - - .slidingNav { - right: -22px; - - &.slidingNavActive { - width: 50vw; - } - - ul { - li { - a { - padding: 1vw 12px; - } - } - } - } - } - } - } - - .gridBlock { - margin: -20px; - overflow: auto; - padding: 1vh 0; - - .twoByGridBlock { - box-sizing: border-box; - float: left; - padding: 20px; - text-align: center; - width: 50%; - } - - .centerInGrid { - margin-left: 25%; - } - - .leftBlock { - padding: 40px 20px; - } - } - - .mainContainer { - .mainWrapper { - nav.toc { - h3 { - padding-top: 0.4em; - } - - ul li a { - margin-bottom: 0; - padding-bottom: 0.2vh; - padding-top: 0; - display: block; - } - - .navToggle { - top: 12px; - } - } - - .post { - padding: 4vw 4vw 4em; - - h2 { - font-size: 180%; - } - - h3 { - font-size: 120%; - } - - .post-header { - padding: 1em 0; - } - - .docPagination { - a { - .pagerLabel { - display: none; - } - .pagerTitle { - display: inline; - } - } - } - } - } - } -} - -@media only screen and (min-width: 900px) { - .homeContainer { - .homeWrapper { - padding-bottom: 4em; - position: relative; - - #inner { - box-sizing: border-box; - max-width: 600px; - padding-right: 40px; - } - - .projectLogo { - align-items: center; - bottom: 0; - display: flex; - justify-content: flex-end; - left: 0; - padding: 2em 20px 4em; - position: absolute; - right: 20px; - top: 0; - - img { - height: 100%; - } - } - } - } - - .headerBarContainer { - .navigationWrapper { - nav { - padding: 0 1em; - position: relative; - top: -9px; - - ul { - margin: 0 -0.4em; - li { - display: inline-block; - - a { - padding: 14px 0.4em; - border: 0; - color: $nav-text; - display: inline-block; - - &:hover { - color: $header-text; - } - } - - &.navItemActive { - a { - color: $header-text; - } - } - } - } - } - - &.navigationFull { - display: inline-block; - } - - &.navigationSlider { - display: none; - } - } - } -} - -@media only screen and (min-width: 1024px) { - .mainContainer { - .mainWrapper { - nav.toc { - box-sizing: border-box; - display: inline-block; - border-right: 12px solid $secondary-bg; - width: 285px; - vertical-align: top; - - .navToggle { - display: none; - } - - .toggleNav { - section { - .navGroup { - display: block; - - h3 { - display: block; - } - - ul li { - display: block; - } - } - - ul li { - display: block; - padding-bottom: 4px; - } - } - } - ul li a { - font-size: 14px; - padding-bottom: 0.1vh; - } - } - - .post { - box-sizing: border-box; - display: inline-block; - padding: 2vw 24px 4em; - width: 590px; - - .post-header { - h1 { - font-size: 250%; - } - } - } - - .posts { - display: inline-block; - width: 590px; - - .post { - margin-bottom: 4vh; - width: 100%; - } - } - } - } -} - -@media only screen and (min-width: 1040px) { - .mainContainer { - .mainWrapper { - nav.toc { - width: 300px; - } - } - } -} - -@media only screen and (min-width: 1200px) { - .homeContainer { - .homeWrapper { - #inner { - max-width: 750px; - } - } - } - - .headerBarContainer { - header { - max-width: 1100px; - } - } - - .wrapper { - max-width: 1100px; - } - - .mainContainer .mainWrapper { - .post, .posts { - width: 760px; - } - } -} - -@media only screen and (min-width: 1500px) { - .homeContainer { - .homeWrapper { - #inner { - max-width: 1100px; - padding-bottom: 40px; - padding-top: 40px; - } - } - } - - .headerBarContainer { - header { - max-width: 1400px; - } - } - - .wrapper { - max-width: 1400px; - } - - .mainContainer .mainWrapper { - .post, .posts { - width: 1035px; - } - } -} diff --git a/docs/_sass/_reset.scss b/docs/_sass/_reset.scss deleted file mode 100644 index 27acba5c06..0000000000 --- a/docs/_sass/_reset.scss +++ /dev/null @@ -1,43 +0,0 @@ -html, body, div, span, applet, object, iframe, -h1, h2, h3, h4, h5, h6, p, blockquote, pre, -a, abbr, acronym, address, big, cite, code, -del, dfn, em, img, ins, kbd, q, s, samp, -small, strike, strong, sub, sup, tt, var, -b, u, i, center, -dl, dt, dd, ol, ul, li, -fieldset, form, label, legend, -table, caption, tbody, tfoot, thead, tr, th, td, -article, aside, canvas, details, embed, -figure, figcaption, footer, header, hgroup, -menu, nav, output, ruby, section, summary, -time, mark, audio, video { - margin: 0; - padding: 0; - border: 0; - font-size: 100%; - font: inherit; - vertical-align: baseline; -} -/* HTML5 display-role reset for older browsers */ -article, aside, details, figcaption, figure, -footer, header, hgroup, menu, nav, section { - display: block; -} -body { - line-height: 1; -} -ol, ul { - list-style: none; -} -blockquote, q { - quotes: none; -} -blockquote:before, blockquote:after, -q:before, q:after { - content: ''; - content: none; -} -table { - border-collapse: collapse; - border-spacing: 0; -} \ No newline at end of file diff --git a/docs/_sass/_search.scss b/docs/_sass/_search.scss deleted file mode 100644 index 9cbeff3692..0000000000 --- a/docs/_sass/_search.scss +++ /dev/null @@ -1,116 +0,0 @@ -/** Algolia Doc Search **/ - -::-webkit-input-placeholder { /* Safari, Chrome */ - color: $nav-text; -} -:-moz-placeholder { /* Mozilla Firefox <= 18 */ - color: $nav-text; - opacity: 1; -} -::-moz-placeholder { /* Mozilla Firefox 19+ */ - color: $nav-text; - opacity: 1; -} -:-ms-input-placeholder { /* Internet Explorer */ - color: $nav-text; -} -:placeholder-shown { /* Standard (https://drafts.csswg.org/selectors-4/#placeholder) */ - color: $nav-text; -} - -[type="search"] { - -moz-appearance: textfield; - -webkit-appearance: textfield; - appearance: textfield; -} - -div.algolia-search-wrapper { - display: inline-block; - vertical-align: top; - margin-left: 15px; -} - -@media screen and (max-width: 960px) { - div.algolia-search-wrapper { - display: none; - } -} - -input#algolia-doc-search { - font-family: $header-font-family; - - background: transparent url('/static/search.png') no-repeat left center; - background-size: 16px 16px; - - padding-left: 20px; - margin-left: 10px; - font-size: 16px; - line-height: 20px; - background-color: $nav-bg; - border: none; - color: white; - outline: none; - width: 160px; - - transition: border-color .2s ease, width .2s ease; - -webkit-transition: border-color .2s ease, width .2s ease; - -moz-transition: border-color .2s ease, width .2s ease; - -o-transition: border-color .2s ease, width .2s ease; -} - -input#algolia-doc-search:focus { - border-color: #05A5D1; - width: 240px; -} - -@media screen and (max-width: 1085px) { - input#algolia-doc-search:focus { - width: 178px; - } -} - -.algolia-autocomplete { - vertical-align: top; - font-family: $header-font-family; -} - -/* Bottom border of each suggestion */ -.algolia-docsearch-suggestion { - border-bottom-color: #2F0A57; -} -/* Main category headers */ -.algolia-docsearch-suggestion--category-header { - background-color: #2F0A57; -} -/* Highlighted search terms */ -.algolia-docsearch-suggestion--text .algolia-docsearch-suggestion--highlight { - color: #C897FF; -} -.algolia-docsearch-suggestion--title .algolia-docsearch-suggestion--highlight, -.algolia-docsearch-suggestion--subcategory-column .algolia-docsearch-suggestion--highlight { - color: #4A078E; -} -.algolia-docsearch-suggestion--category-header .algolia-docsearch-suggestion--highlight { - background-color: #C897FF; -} -/* Currently selected suggestion */ -.aa-cursor .algolia-docsearch-suggestion--content { - color: #151515; -} -.aa-cursor .algolia-docsearch-suggestion { - background: #F3E8FF; -} - -/* For bigger screens, when displaying results in two columns */ -@media (min-width: 768px) { - /* Bottom border of each suggestion */ - .algolia-docsearch-suggestion { - border-bottom-color: #2F0A57; - } - /* Left column, with secondary category header */ - .algolia-docsearch-suggestion--subcategory-column { - border-right-color: #2F0A57; - background-color: #E4E4E4; - color: #151515; - } -} diff --git a/docs/_sass/_slideshow.scss b/docs/_sass/_slideshow.scss deleted file mode 100644 index 180f0983cd..0000000000 --- a/docs/_sass/_slideshow.scss +++ /dev/null @@ -1,48 +0,0 @@ -.slideshow { - position: relative; - - .slide { - display: none; - - img { - display: block; - margin: 0 auto; - } - - &.slideActive { - display: block; - } - - a { - border: none; - display: block; - } - } - - .pagination { - display: block; - margin: -10px; - padding: 1em 0; - text-align: center; - width: 100%; - - .pager { - background: transparent; - border: 2px solid rgba(255, 255, 255, 0.5); - border-radius: 50%; - cursor: pointer; - display: inline-block; - height: 12px; - margin: 10px; - transition: background-color 0.3s, border-color 0.3s; - width: 12px; - - &.pagerActive { - background: rgba(255, 255, 255, 0.5); - border-width: 4px; - height: 8px; - width: 8px; - } - } - } -} \ No newline at end of file diff --git a/docs/_sass/_syntax-highlighting.scss b/docs/_sass/_syntax-highlighting.scss deleted file mode 100644 index b84b8bd638..0000000000 --- a/docs/_sass/_syntax-highlighting.scss +++ /dev/null @@ -1,81 +0,0 @@ -/** - * Syntax highlighting styles - */ -.highlighter-rouge { - .c { color: #998; font-style: italic } // Comment - .err { color: #a61717; background-color: #e3d2d2 } // Error - .k { font-weight: bold } // Keyword - .o { font-weight: bold } // Operator - .cm { color: #998; font-style: italic } // Comment.Multiline - .cp { color: #999; font-weight: bold } // Comment.Preproc - .c1 { color: #998; font-style: italic } // Comment.Single - .cs { color: #999; font-weight: bold; font-style: italic } // Comment.Special - .gd { color: #000; background-color: #fdd } // Generic.Deleted - .gd .x { color: #000; background-color: #faa } // Generic.Deleted.Specific - .ge { font-style: italic } // Generic.Emph - .gr { color: #a00 } // Generic.Error - .gh { color: #999 } // Generic.Heading - .gi { color: #000; background-color: #dfd } // Generic.Inserted - .gi .x { color: #000; background-color: #afa } // Generic.Inserted.Specific - .go { color: #888 } // Generic.Output - .gp { color: #555 } // Generic.Prompt - .gs { font-weight: bold } // Generic.Strong - .gu { color: #aaa } // Generic.Subheading - .gt { color: #a00 } // Generic.Traceback - .kc { font-weight: bold } // Keyword.Constant - .kd { font-weight: bold } // Keyword.Declaration - .kp { font-weight: bold } // Keyword.Pseudo - .kr { font-weight: bold } // Keyword.Reserved - .kt { color: #458; font-weight: bold } // Keyword.Type - .m { color: #099 } // Literal.Number - .s { color: #d14 } // Literal.String - .na { color: #008080 } // Name.Attribute - .nb { color: #0086B3 } // Name.Builtin - .nc { color: #458; font-weight: bold } // Name.Class - .no { color: #008080 } // Name.Constant - .ni { color: #800080 } // Name.Entity - .ne { color: #900; font-weight: bold } // Name.Exception - .nf { color: #900; font-weight: bold } // Name.Function - .nn { color: #555 } // Name.Namespace - .nt { color: #000080 } // Name.Tag - .nv { color: #008080 } // Name.Variable - .ow { font-weight: bold } // Operator.Word - .w { color: #bbb } // Text.Whitespace - .mf { color: #099 } // Literal.Number.Float - .mh { color: #099 } // Literal.Number.Hex - .mi { color: #099 } // Literal.Number.Integer - .mo { color: #099 } // Literal.Number.Oct - .sb { color: #d14 } // Literal.String.Backtick - .sc { color: #d14 } // Literal.String.Char - .sd { color: #d14 } // Literal.String.Doc - .s2 { color: #d14 } // Literal.String.Double - .se { color: #d14 } // Literal.String.Escape - .sh { color: #d14 } // Literal.String.Heredoc - .si { color: #d14 } // Literal.String.Interpol - .sx { color: #d14 } // Literal.String.Other - .sr { color: #009926 } // Literal.String.Regex - .s1 { color: #d14 } // Literal.String.Single - .ss { color: #990073 } // Literal.String.Symbol - .bp { color: #999 } // Name.Builtin.Pseudo - .vc { color: #008080 } // Name.Variable.Class - .vg { color: #008080 } // Name.Variable.Global - .vi { color: #008080 } // Name.Variable.Instance - .il { color: #099 } // Literal.Number.Integer.Long -} - -.highlighter-rouge pre code { - background: #f0f0f0; - color: #000; - display: block; - font-family: monospace; - font-size: 12px; - margin: 1em 0; - overflow-x: auto; - padding: 12px; - text-align: left; -} - -code { - color: $primary-bg; - font-family: monospace; -} diff --git a/docs/_sass/_tables.scss b/docs/_sass/_tables.scss deleted file mode 100644 index f5b97395f5..0000000000 --- a/docs/_sass/_tables.scss +++ /dev/null @@ -1,46 +0,0 @@ -table { - background: $lightergrey; - border: 1px solid $lightgrey; - border-collapse: collapse; - display:table; - - thead { - border-bottom: 1px solid $lightgrey; - display: table-header-group; - } - tbody { - display: table-row-group; - } - tr { - display: table-row; - &:nth-of-type(odd) { - background: $greyish; - } - - th, td { - border-right: 1px dotted $lightgrey; - display: table-cell; - font-size: 14px; - line-height: 1.3em; - padding: 10px; - text-align: left; - - &:last-of-type { - border-right: 0; - } - - code { - color: $green; - display: inline-block; - font-size: 12px; - } - } - - th { - color: #000000; - font-weight: bold; - font-family: $header-font-family; - text-transform: uppercase; - } - } -} diff --git a/docs/_top-level/support.md b/docs/_top-level/support.md deleted file mode 100644 index a481475d9e..0000000000 --- a/docs/_top-level/support.md +++ /dev/null @@ -1,32 +0,0 @@ ---- -layout: top-level -id: support -category: support ---- - -## Need help? - -Do not hesitate to ask questions using the following channels, or to -[submit a pull request](https://github.com/facebook/nuclide/pulls)! - -### GitHub issues - -The [GitHub issues](https://github.com/facebook/nuclide/issues) page is a good place to ask -questions, find answers, and report issues. - -### Facebook Group - - - -### FAQ - -Check out a list of [commonly asked questions](/docs/help/faq) about Nuclide. - -### Troubleshooting - -Have installation or other issues, check out our -[troubleshooting section](/docs/help/troubleshooting). - -### Uninstalling Nuclide - -To remove Nuclide and its dependencies, follow the [uninstall instructions](/docs/editor/uninstall). diff --git a/docs/blog/all.html b/docs/blog/all.html deleted file mode 100644 index 884823f024..0000000000 --- a/docs/blog/all.html +++ /dev/null @@ -1,19 +0,0 @@ ---- -id: blog -title: All Posts … -layout: blog ---- - -
-
-

All Posts

-
-
    - {% for post in site.posts %} -
  • - {{ post.title }} - on {{ post.date | date: '%d %B %Y' }} -
  • - {% endfor %} -
-
diff --git a/docs/blog/index.md b/docs/blog/index.md deleted file mode 100644 index 4c9d550c5b..0000000000 --- a/docs/blog/index.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -id: blog -title: Blog -layout: redirect -destination: / ---- diff --git a/docs/css/main.scss b/docs/css/main.scss deleted file mode 100644 index 4867e89ba2..0000000000 --- a/docs/css/main.scss +++ /dev/null @@ -1,84 +0,0 @@ ---- -# Only the main Sass file needs front matter (the dashes are enough) ---- -@charset "utf-8"; - - - -// Our variables -$base-font-family: "Segoe UI", Helvetica, sans-serif; -$header-font-family: "Gotham Rounded A", "Gotham Rounded B", 'Helvetica Neue', Arial, sans-serif; -$base-font-size: 16px; -$small-font-size: $base-font-size * 0.875; -$base-line-height: 1.4em; - -$spacing-unit: 12px; - -$text: {{ site.color.bodytext }}; -$header-text: {{ site.color.headertext }}; -$primary-bg: {{ site.color.primary }}; -$secondary-bg: {{ site.color.secondary }}; -$light-color: {{ site.color.light }}; -$light-text-color: {{ site.color.lighttext }}; -$nav-bg: {{ site.color.primary }}; -$nav-text: {{ site.color.navtext }}; -$footer-bg: #1F242A; -$link-color: {{ site.color.link }}; - -$header-height: 34px; -$header-ptop: 10px; -$header-pbot: 8px; - -// Width of the content area -$content-width: 900px; - -// Table setting variables -$lightergrey: #F8F8F8; -$greyish: #E8E8E8; -$lightgrey: #B0B0B0; -$green: #2db04b; - -// Using media queries with like this: -// @include media-query($on-palm) { -// .wrapper { -// padding-right: $spacing-unit / 2; -// padding-left: $spacing-unit / 2; -// } -// } -@mixin media-query($device) { - @media screen and (max-width: $device) { - @content; - } -} - - - -// Import partials from `sass_dir` (defaults to `_sass`) -@import - "reset", - "base", - "search", - "slideshow", - "syntax-highlighting", - "tables" -; - -// Anchor links -// http://ben.balter.com/2014/03/13/pages-anchor-links/ -.header-link { - position: absolute; - margin-left: 0.2em; - opacity: 0; - - -webkit-transition: opacity 0.2s ease-in-out 0.1s; - -moz-transition: opacity 0.2s ease-in-out 0.1s; - -ms-transition: opacity 0.2s ease-in-out 0.1s; -} - -h2:hover .header-link, -h3:hover .header-link, -h4:hover .header-link, -h5:hover .header-link, -h6:hover .header-link { - opacity: 1; -} diff --git a/docs/doc-type-examples/2016-04-07-blog-post-example.md b/docs/doc-type-examples/2016-04-07-blog-post-example.md deleted file mode 100644 index ef954d63a7..0000000000 --- a/docs/doc-type-examples/2016-04-07-blog-post-example.md +++ /dev/null @@ -1,21 +0,0 @@ ---- -title: Blog Post Example -layout: post -author: exampleauthor -category: blog ---- - -Any local blog posts would go in the `_posts` directory. - -This is an example blog post introduction, try to keep it short and about a paragraph long, to encourage people to click through to read the entire post. - - - -Everything below the `` tag will only show on the actual blog post page, not on the `/blog/` index. - -Author is defined in `_data/authors.yml` - - -## No posts? - -If you have no blog for your site, you can remove the entire `_posts` folder. Otherwise add markdown files in here. See CONTRIBUTING.md for details. diff --git a/docs/doc-type-examples/docs-hello-world.md b/docs/doc-type-examples/docs-hello-world.md deleted file mode 100644 index c7094ba5af..0000000000 --- a/docs/doc-type-examples/docs-hello-world.md +++ /dev/null @@ -1,12 +0,0 @@ ---- -docid: hello-world -title: Hello, World! -layout: docs -permalink: /docs/hello-world.html ---- - -Any local docs would go in the `_docs` directory. - -## No documentation? - -If you have no documentation for your site, you can remove the entire `_docs` folder. Otherwise add markdown files in here. See CONTRIBUTING.md for details. diff --git a/docs/doc-type-examples/top-level-example.md b/docs/doc-type-examples/top-level-example.md deleted file mode 100644 index 67b1fa7110..0000000000 --- a/docs/doc-type-examples/top-level-example.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -layout: top-level -title: Support Example -id: top-level-example -category: top-level ---- - -This is a static page disconnected from the blog or docs collections that can be added at a top-level (i.e., the same level as `index.md`). diff --git a/docs/docs/index.html b/docs/docs/index.html deleted file mode 100644 index d70536aafe..0000000000 --- a/docs/docs/index.html +++ /dev/null @@ -1,6 +0,0 @@ ---- -id: docs -title: Docs -layout: redirect -destination: quick-start/getting-started/ ---- diff --git a/docs/index.md b/docs/index.md deleted file mode 100644 index f4532dc9e5..0000000000 --- a/docs/index.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -layout: home -id: home ---- - -{% include content/gridblocks.html data_source=site.data.features grid_type="twoByGridBlock" %} - - -
- This project is unrelated to the CSS framework project named Nuclide. -
\ No newline at end of file diff --git a/docs/js/docsearch.js b/docs/js/docsearch.js deleted file mode 100644 index 2f24833697..0000000000 --- a/docs/js/docsearch.js +++ /dev/null @@ -1,25 +0,0 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the license found in the LICENSE file in - * the root directory of this source tree. - * - * @noflow - */ -'use strict'; - -/* eslint comma-dangle: [1, always-multiline], prefer-object-spread/prefer-object-spread: 0 */ - -/* eslint-disable no-var */ -/* eslint-disable no-undef */ - -// For Algolia search -(function() { - // Algolia - docsearch({ - apiKey: '421f79d033cee73a376aba52e4f572eb', - indexName: 'nuclide', - inputSelector: '#algolia-doc-search', - }); -})(); diff --git a/docs/js/get-required-versions.js b/docs/js/get-required-versions.js deleted file mode 100644 index b3905c7a88..0000000000 --- a/docs/js/get-required-versions.js +++ /dev/null @@ -1,60 +0,0 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the license found in the LICENSE file in - * the root directory of this source tree. - * - * @noflow - */ -'use strict'; - -/* eslint comma-dangle: [1, always-multiline], prefer-object-spread/prefer-object-spread: 0 */ -/* eslint-disable prefer-arrow-callback */ -/* eslint-disable no-var */ -/* eslint-disable no-undef */ - -(function() { - if (typeof fetch !== 'function') { - // Your browser is too old... - return; - } - - // Not supported on all browsers, but is on modern browsers that - // will be used by 99% of the people accessing the site. - var nodeEls = document.getElementsByClassName('node'); - var atomEls = document.getElementsByClassName('atom'); - var nuclideEls = document.getElementsByClassName('nuclide'); - - if (!(nodeEls.length > 0 || atomEls.length > 0 || nuclideEls.length > 0)) { - // Nothing to do in this page... - return; - } - - fetch( - 'https://raw.githubusercontent.com/facebook/nuclide/master/package.json', - {mode: 'cors'} - ).then(function(response) { - return response.json(); - }).then(function(data) { - // Get the first part that looks like a version... - var versionLikeRe = /\b\d+\.\d+\.\d+\b/; - - var nodeVersion = data.engines.node.match(versionLikeRe)[0]; - var atomVersion = data.engines.atom.match(versionLikeRe)[0]; - var nuclideVersion = data.version; - - for (var i = 0; i < nodeEls.length; i++) { - nodeEls.item(i).innerHTML = - 'A Node version that is greater or equal to ' + nodeVersion + ' is required.'; - } - for (var j = 0; j < atomEls.length; j++) { - atomEls.item(j).innerHTML = - 'Nuclide requires an Atom version that is greater or equal to ' + atomVersion + '.'; - } - for (var k = 0; k < nuclideEls.length; k++) { - nuclideEls.item(k).innerHTML = - 'The current version of Nuclide is ' + nuclideVersion + '.'; - } - }); -})(); diff --git a/docs/js/jekyll-link-anchors.js b/docs/js/jekyll-link-anchors.js deleted file mode 100644 index 838d40bc12..0000000000 --- a/docs/js/jekyll-link-anchors.js +++ /dev/null @@ -1,84 +0,0 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the license found in the LICENSE file in - * the root directory of this source tree. - * - * @noflow - */ -'use strict'; - -/* eslint comma-dangle: [1, always-multiline], prefer-object-spread/prefer-object-spread: 0 */ - -/* eslint-disable no-var */ -/* eslint-disable prefer-arrow-callback */ - -// Taken and modified from https://gist.github.com/SimplGy/a229d25cdb19d7f21231 -(function() { - // Create intra-page links - // Requires that your headings already have an `id` attribute set (because that's what jekyll - // does). For every heading in your page, this adds a little anchor link `#` that you can click - // to get a permalink to the heading. Ignores `h1`, because you should only have one per page. - - // This also allows us to have uniquely named links even with headings of the same name. - // e.g., - // h2: Mac (#mac) - // h3: prerequisites (#mac__prerequisites) - // h2: Linux (#linux) - // h3: prerequisites (#linux__prerequisites) - - // We don't want anchors for any random h2 or h3; only ones with an - // id attribute which aren't in h2's and h3's in the sidebar ToC and - // header bar. - var possibleNodeNames = ['h2', 'h3', 'h4', 'h5']; // Really try to only have up to h3, please - var tags = document.querySelectorAll('h2[id], h3[id], h4[id], h5[id]'); - var headingNodes = Array.prototype.slice.call(tags); - - headingNodes.forEach(function(node) { - var nameIdx = possibleNodeNames.indexOf(node.localName); // h2 = 0, h3 = 1, etc. - var link; - var id; - var psib; - var suffix; - - // Remove automatic id suffix added by kramdown if heading with same name exists. - // e.g., - // h2: Mac - // h3: prerequisites (id = prerequisites) - // h2: Linux - // h3: prerequisites (id = prerequisites-1) - - // Only match at end of string since that is where auto suffix wil be added. - suffix = node.getAttribute('id').match(/-[0-9]+$/); - // If the -1, etc. suffix exists, make sure someone didn't purposely put the suffix there - // by checking against the actual text associated with the node - if (suffix !== null && - node.getAttribute('id').substring(0, suffix.index) === node.textContent.toLowerCase()) { - node.setAttribute('id', node.textContent.toLowerCase()); - } - - link = document.createElement('a'); - link.className = 'header-link'; - link.textContent = '#'; - id = ''; - - // Avoid duplicate anchor links - // If we are at an h3, go through the previous element siblings of this node, and find its - // h2 parent and append it to the href text. - psib = node.previousElementSibling; - var idx; - while (psib) { - // Find the parent, if it exists. - idx = possibleNodeNames.indexOf(psib.localName); - if (idx !== -1 && idx === nameIdx - 1) { // if we are at h3, we want h2. That's why the - 1 - id += psib.getAttribute('id') + '__'; - break; - } - psib = psib.previousElementSibling; - } - link.id = id + node.getAttribute('id'); - link.href = '#' + link.id; - node.appendChild(link); - }); -})(); diff --git a/docs/static/favicon.png b/docs/static/favicon.png deleted file mode 100644 index 9e0eaf4a11..0000000000 Binary files a/docs/static/favicon.png and /dev/null differ diff --git a/docs/static/fonts/332720/11F30310EFD3175B0.css b/docs/static/fonts/332720/11F30310EFD3175B0.css deleted file mode 100644 index 06c864d7a7..0000000000 --- a/docs/static/fonts/332720/11F30310EFD3175B0.css +++ /dev/null @@ -1,19 +0,0 @@ - -/* - Copyright (C) 2011-2015 Hoefler & Co. - This software is the property of Hoefler & Co. (H&Co). - Your right to access and use this software is subject to the - applicable License Agreement, or Terms of Service, that exists - between you and H&Co. If no such agreement exists, you may not - access or use this software for any purpose. - This software may only be hosted at the locations specified in - the applicable License Agreement or Terms of Service, and only - for the purposes expressly set forth therein. You may not copy, - modify, convert, create derivative works from or distribute this - software in any way, or make it accessible to any third party, - without first obtaining the written permission of H&Co. - For more information, please visit us at http://typography.com. - 171247-88474-20150623 -*/ - -@font-face{ font-family: "Gotham Rounded A"; src: url(data:application/x-font-woff;base64,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))); font-weight:300; font-style:normal; } @font-face{ font-family: "Gotham Rounded B"; src: url(data:application/x-font-woff;base64,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); font-weight:300; font-style:normal; } \ No newline at end of file diff --git a/docs/static/fonts/332720/143BB439096CFDFC4.css b/docs/static/fonts/332720/143BB439096CFDFC4.css deleted file mode 100644 index 93e7cb801c..0000000000 --- a/docs/static/fonts/332720/143BB439096CFDFC4.css +++ /dev/null @@ -1,19 +0,0 @@ - -/* - Copyright (C) 2011-2015 Hoefler & Co. - This software is the property of Hoefler & Co. (H&Co). - Your right to access and use this software is subject to the - applicable License Agreement, or Terms of Service, that exists - between you and H&Co. If no such agreement exists, you may not - access or use this software for any purpose. - This software may only be hosted at the locations specified in - the applicable License Agreement or Terms of Service, and only - for the purposes expressly set forth therein. You may not copy, - modify, convert, create derivative works from or distribute this - software in any way, or make it accessible to any third party, - without first obtaining the written permission of H&Co. - For more information, please visit us at http://typography.com. - 171247-88474-20150623 -*/ - -@font-face{ font-family: "Gotham Rounded A"; src: url(data:font/opentype;base64,MgA/Al0APwA9ACoCOgBdA1MAZQIzAD8BXQA/AToAPwI8AD8CSQA/AmgAFgNvABIBaAA/AmgAPwI1AD8DQgA/AjcAdgJAAD8CPABdAjcAYgIsAE4CHgBPAUEAPwI9AHgCXQA/AAAALAEAAD8BCgA/PwEAAQAAAAIAAAAEAAEAGgABAAEAAgAAAAAAGAAAAA4AAAABAAALHz8/P35/Pz9/fz8/Pz8/Pz8LHz8/P38/Pz8/Pz8/Pz8/Pz8LHj8/Pz8GfR8/Pz8/Cx8/Pz8/CD8/Pz8/PwY/CD8/Pz8/Px8/Pz9/fz8/Pwg/fT8/Pz9YRjQnAQEEABM/FT8/FBY/Dh8/Pz8/Pz8/Pz8/Pz8/Pz8/FT9YPwc/Yj8/bj8/P3V7Pz8Gbj8/Pz8/Pz8/eT8/Pz8/FWhzPwohFT8/CiAVPz8/CH54P30/Pz90Pz8/P3w/fD97PxU/PwU/CD8/Pz8/Pz8/Pz8/Px4/Pz8/Pz8/PxU/Fz8HfT8fPz8/Pz8/Pz8ePz8/Pz8/Pz8VPxs/CD8/Pz8/Pz8/Pz8/Pz8/Pz8/Px8/Pz8/FXBoBj8/CD8/Pz8/Pz8/Pz8/Pz8/Pz8/PwU/Pwg/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8ePz8/Pz8/Pz8IPz8/Pz8/Pz8/Pz8/Pz8/Pz8/Bz8/FVt3Pwc/cj8/ej8IPz8/Pz8/Hj8/Pz8HPz8/Pz8/eR4/Pz8/Pz8/PwY/Pz8/FXw/ZT8IPz8/Pz8/P3I/ej93P3Z/f3o/BT8/CD8/Pz8/Pz8/Pz9pPz8/Pz8/Pz9jP1Y/YT9sbnlWdT95P24/HmBhYUhNP2o/CD8/Pz8/Pz9wP3c/P3N7fXg/ch9vP3U/Pz8/Pwg/Pz8/fD8VSj8iPwc/fj8/Px8/Pz8/CD8/Pz8/PwU/Pwg/Pz8/Pz8ePz8/Pwd3Pz8/PxUqPwg/P3Q/bD98P30/Pz8/eT9vP28/Pz8/Pz8VFz9iBj8IPz8/Pz8/Pz8/Pz8/Pz8/P3s/Pz8/Pz8/Pz8/Pz8/BT8/Bj8/Pwg/Pz8/Pz8/Pz8/Pz8/Pz9zPz8/Pz8/Pz8/Pz8/Pz8FPz8/PxU/Px56fz97ej9/Pwg/Pz8/Pz91P30/dD8VPz8tPwg/Pz8/Pz8/Pz8/Pz8/P3Q/Pz8FPz8/Pz9yPz8/Pz8/dz8/Pz8/P3o/Pz8/Pz8IPz8/Pz8/Hz8/Pz8/Pz8/FVk/Bz8/eT8IPz8/Pz8/Hz8/Pz8/Pz8/CD8/Pz8/PwU/Pz8/FT97Bz9yPz95Pwg/Pz8/Pz8ePz8/Pz8/Pz8/Pz8/Bz8IPz8/Pz8/Bj8/Pz8VPwc/cj8/Pz8ffj8/Pwg/Pz8/Pz8FPz8GPz8/Pz8/cj8/Pz8/FTsrHz8/Pz8/Pz8/Pz8/Pz8/Pz8VPxI/Hz8/P3p5f359CD8/Pz8/PwU/PwY/Pz8Ifz8/Pz8/Hz8/Pz8/Pz8/CD8/Pz8/PwY/CD8/Pz8/PxVRPyY/Bj8/Pz8VQT9VPwojFT8GP2I/P1g/Pwg/Pz8/Pz8GPz8/CD8/Pz8/PwY/Pz8IPz8/Pz8/Bj8/Pz8/FT85PwojBD8KIhU/PwojBD8KIhVBPwoiFT9QCiEVPz8KIBU/Pw4ePz8/Pz99P3gHcB54fX14eD99Pwc/FQI/Px8/Pz8/Bj8ePz8/fQV3P3sePz8/Pz8/Pz8VPz8hPz8OHj8/Pz8HPwg/Pz8/Pz8FPD8/Pz8fPz8/f38/P38GEz8efz8/Pwc/CD8/Pz8/PwU8Pz8/H38/Pz8/Pz8/BiE/Fj9aDgg/Pz8/fT8FXz87Pwg/Pz8/Pz9+Pz9/P30/fT8/Pz8FQz8oP0U/KD8IPz8/Pz9+Bj8IP30/Pz8/BUU/KD9FPyk/CD8/Pz8/fT99Pz8/Pz8/Pz8/PwVfPzs/CD8/Pz8/PwY/CD8/Pz98PwU1PyU/NT8mPwg/Pz8/Pz8GPxU/Pz8/Pw4ePz8/Pz8/P3wHQQg/Pz8/HhU/Mz8OPwc/Px58Pz99fT8/Pwc/Px4/P1AkJz8+IQc/Px58Pz99fT8/PxV9Pz8/Pw4IP3A/ZD8/Pz8/Pz9+Pz8/P34/Pz8/Pz8/Vj9TP04eRmVVUAc/CE8/dT93P3M/cj8wPwc/HzlQRigIP1Q/Tj9aPz8/Pz8/Pz8/Pz8/Pz8/Pz8/cT97Pz8/Hj8/Pz8HPwg/Pz9GP0I/OT81Pz8HPx8/Pz8/FT8/PyEOHn0/P319Pz8/BxA/CChfVTI/Qz98Pz8/Pz8/Pz8/Pz8APz84Pz8HUD8ePz8/Pz8/P3wVP18/Dh4NPyg0DD8HPx4PPyk/Cj8NPz8MPwc/Hw8/Lwo/FT8/His/Dj8CPyM/Bz8eIz8QPwM/LD8rPw4/Aj8jPwc/HyM/ED8DPyw/FX8/Pz8OHgM/Px0/Bz8eGj8uICEyJRY/Bz8fFz8zPz8VWj8/Px4/Pz8/Pz8/fAcuCD8/Pz8eDz8oET86Pwc/Hzo/JhE/Dz8IPyU/ST9hBz8/Hnw/P319Pz8/FVk/Pw4IPz8/Pz8/BT8/Pz8/Pz8IPz8/Pz8/fz9/fz9+Pz8/Pz8/BT8/fD8/P3k/CD8/Pz8/Pz9+Pz8/Pz8/Pz8/PwU/Pz8/Pz8/CD8/Pz8/Pz8/Pz8/Pz8/Pz8/PwU/Pz8/Pz8/CD8/Pz8/Px4/Pz9+FT8LPw4ffX9/fQY/CD8/Pz8/PwU/P2w/Pz8efT8/fX0/Pz8HKD8fPz8/PwY/CD8/Pz8/PwU/P3U/Pz8ePz8/Pz8/P30VP08/Dh59f399fT9/PwckPx4/Pz8/P38/fRU/Az8/Dh59f399fT9/Pwc/P1Q/Px59f399fT9/PwckPx4/Pz8/P38/fQc/P1Q/Px4/Pz8/P38/fRU/MT8OHj9/P30HHD8ffX9/fQZYPx9+Pz8/Pz8/PwY+Pz8/ET8ffj8/Pz8/Pz8GET8/P0M/H34/Pz8/Pz8/Bl0/FhY/Dh8tLDUpPE8/Pz8/PwQ/P1Q9FT8/Vh8/P1k/Uj8/Pz8/Wz9VPz8/Pz9NP1M/Zz8/Pz8/CD9nP1I/Pz8/Pz8fP0M/ISM/IQ0/BD8IPzo/Xj90BVA/CHw/Pz8/fj97Pz8/PwVWPz8IPz8/Pz8/Hz8/alJFTUElP0s/ST9AP3o/ez9LP0E/cz90P0g/Pz8/Pwg/KXVEYUE/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8VNj8/Pw0/Dh4LPzE/Mwc/Hig8Pwg/Bz8/Pwc/Hz8/PAM/FT8/Pwg/aT9gPwg/Pz8/Pz99P38/P30/Pz8/Pz8/VT9WP08/IT8rPyhmPz8/Pz8CPx4hPy0/DD8HPx8VPyEnJj8IP0A/Tj9hP1U/aSA/Pwc/H3A/Mj8OPzc/FX8/Pw4eFT9GPjwHPx40TD8GPwY/Pz8HPx8/Pz4VPwQ/Px4oUTg1Bz8ePFI/Pz8/Pz8HPx8/PzgoBBs/Hic/OgU/CD8HPwg5P01IbjNvP1c/OD8HPx4BP0EHPw0/DT8HPwE/Bz8IPz8/Pz8zP0g/Pwc/Hwg/BT8nPxU/Pz8OHgU/OUEoBz8eK0M/Az8HPz8/Bz8fPz82BT8VPz8IP28/YT9RP0U/JT8/Bz8fZz88PwM/Qj8IP0E/Uj9TCD8/Pz8/Pz8/Pz8/Pz8/Pz8/P2I/dT8/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GAEWARQBEgEPAT8APwA/AD8APwB6AHcAdQBzAG8AZABYAE4ASQBFAEAAOQA2ADMAJAAhADgABQBAAHgAAAAYAgQAHAAAAAEAAwA0AgAAAAABABwAAAADAAAAAwAAAABlAHIAYQB3AHQAZgBvAHMALQB0AG4AbwBmAGIAZQB3AC8AbQBvAGMALgB5AGgAcABhAHIAZwBvAHAAeQB0AC4AdwB3AHcALwAvADoAcAB0AHQAaABtAG8AYwAuAHkAaABwAGEAcgBnAG8AcAB5AHQALgB3AHcAdwA5ADEAMgAwADQAMQAtADMAMgA0ADIALQAzADIANgAwADUAMQAwADIALQA0ADcANAA4ADgALQA3ADQAMgAxADcAMQAgAG0AbwBjAC4AeQBoAHAAYQByAGcAbwBwAHkAdAAuAHcAdwB3ACAAdABhACAALgBvAEMAIAAmACAAcgBlAGwAZgBlAG8ASAAgAHQAYwBhAHQAbgBvAGMAIAByAG8AIAAsAGUAcgBhAHcAdABmAG8AcwAtAHQAbgBvAGYAYgBlAHcALwBtAG8AYwAuAHkAaABwAGEAcgBnAG8AcAB5AHQALgB3AHcAdwAvAC8AOgBwAHQAdABoACAAdABpAHMAaQB2ACAAZQBzAGEAZQBsAHAAIAAsAG4AbwBpAHQAYQBtAHIAbwBmAG4AaQAgAGUAcgBvAG0AIAByAG8ARgAgAC4AZQBzAG8AcAByAHUAcAAgAHkAbgBhACAAcgBvAGYAIABlAHIAYQB3AHQAZgBvAHMAIABzAGkAaAB0ACAAZQBzAHUAIAB0AG8AbgAgAHkAYQBtACAAdQBvAHkAIAAsAHMAdABzAGkAeABlACAAdABuAGUAbQBlAGUAcgBnAGEAIABoAGMAdQBzACAAbwBuACAAZgBJACAALgBvAEMAIAAmACAAcgBlAGwAZgBlAG8ASAAgAGQAbgBhACAAdQBvAHkAIABuAGUAZQB3AHQAZQBiACAAcwB0AHMAaQB4AGUAIAB0AGEAaAB0ACAAdABuAGUAbQBlAGUAcgBnAGEAIABlAGMAaQB2AHIAZQBTACAAZgBvACAAcwBtAHIAZQBUACAAZQBoAHQAIABvAHQAIAB0AGMAZQBqAGIAdQBzACAAcwBpACAAZQByAGEAdwB0AGYAbwBzACAAcwBpAGgAdAAgAGUAcwB1ACAAbwB0ACAAdABoAGcAaQByACAAcgB1AG8AWQAgAC4AbgBvAGkAdABhAGMAbwBsACAAeQBuAGEAIABtAG8AcgBmACAAdABpACAAdABzAG8AaAAgAHIAbwAgACwAcgBlAHQAdQBwAG0AbwBjACAAeQBuAGEAIABuAG8AcAB1ACAAdABpACAAbABsAGEAdABzAG4AaQAgAHIAbwAgACwAZQByAGEAdwB0AGYAbwBzACAAcwBpAGgAdAAgAGQAYQBvAGwAbgB3AG8AZAAgAHIAbwAgACwAZQB0AHUAYgBpAHIAdABzAGkAZAAgACwAeQBmAGkAZABvAG0AIAAsAHkAcABvAGMAIAB0AG8AbgAgAHkAYQBtACAAdQBvAFkAIAAuAG8AQwAgACYAIAByAGUAbABmAGUAbwBIACAAZgBvACAAeQB0AHIAZQBwAG8AcgBwACAAZQBoAHQAIABzAGkAIABlAHIAYQB3AHQAZgBvAHMAIABzAGkAaABUAC4AbwBDACAAJgAgAHIAZQBsAGYAZQBvAEgALgBzAG4AbwBpAHQAYwBpAGQAcwBpAHIAdQBqACAAbgBpAGEAdAByAGUAYwAgAG4AaQAgAGQAZQByAGUAdABzAGkAZwBlAHIAIABlAGIAIAB5AGEAbQAgAGgAYwBpAGgAdwAgACwALgBvAEMAIAAmACAAcgBlAGwAZgBlAG8ASAAgAGYAbwAgAGsAcgBhAG0AZQBkAGEAcgB0ACAAYQAgAHMAaQAgAGQAZQBkAG4AdQBvAFIAIABtAGEAaAB0AG8ARwB0AG4AbwBGADEAMAAyAC4AMQAgAG4AbwBpAHMAcgBlAFYAOQAxADIAMAA0ADEALQAzADIANAAyAC0AMwAyADYAMAA1ADEAMAAyAC0ANAA3ADQAOAA4AC0ANwA0ADIAMQA3ADEAcgBhAGwAdQBnAGUAUgBtAG8AYwAuAHkAaABwAGEAcgBnAG8AcAB5AHQAIAB8ACAAbwBDACYASAAgACkAQwAoACAAdABoAGcAaQByAHkAcABvAEMAbQBvAGMALgB5AGgAcABhAHIAZwBvAHAAeQB0AC4AdwB3AHcALwAvADoAcAB0AHQAaAAgAC4AbwBDACAAJgAgAHIAZQBsAGYAZQBvAEgAIAA3ADAAMAAyACAALAA2ADAAMAAyACAAKQBDACgAIAB0AGgAZwBpAHIAeQBwAG8AQwBlcmF3dGZvcy10bm9mYmV3L21vYy55aHBhcmdvcHl0Lnd3dy8vOnB0dGhtb2MueWhwYXJnb3B5dC53d3c5MTIwNDEtMzI0Mi0zMjYwNTEwMi00NzQ4OC03NDIxNzEgbW9jLnlocGFyZ29weXQud3d3IHRhIC5vQyAmIHJlbGZlb0ggdGNhdG5vYyBybyAsZXJhd3Rmb3MtdG5vZmJldy9tb2MueWhwYXJnb3B5dC53d3cvLzpwdHRoIHRpc2l2IGVzYWVscCAsbm9pdGFtcm9mbmkgZXJvbSByb0YgLmVzb3BydXAgeW5hIHJvZiBlcmF3dGZvcyBzaWh0IGVzdSB0b24geWFtIHVveSAsc3RzaXhlIHRuZW1lZXJnYSBoY3VzIG9uIGZJIC5vQyAmIHJlbGZlb0ggZG5hIHVveSBuZWV3dGViIHN0c2l4ZSB0YWh0IHRuZW1lZXJnYSBlY2l2cmVTIGZvIHNtcmVUIGVodCBvdCB0Y2VqYnVzIHNpIGVyYXd0Zm9zIHNpaHQgZXN1IG90IHRoZ2lyIHJ1b1kgLm5vaXRhY29sIHluYSBtb3JmIHRpIHRzb2ggcm8gLHJldHVwbW9jIHluYSBub3B1IHRpIGxsYXRzbmkgcm8gLGVyYXd0Zm9zIHNpaHQgZGFvbG53b2Qgcm8gLGV0dWJpcnRzaWQgLHlmaWRvbSAseXBvYyB0b24geWFtIHVvWSAub0MgJiByZWxmZW9IIGZvIHl0cmVwb3JwIGVodCBzaSBlcmF3dGZvcyBzaWhULm9DICYgcmVsZmVvSC5zbm9pdGNpZHNpcnVqIG5pYXRyZWMgbmkgZGVyZXRzaWdlciBlYiB5YW0gaGNpaHcgLC5vQyAmIHJlbGZlb0ggZm8ga3JhbWVkYXJ0IGEgc2kgZGVkbnVvUiBtYWh0b0d0bm9GMTAyLjEgbm9pc3JlVjkxMjA0MS0zMjQyLTMyNjA1MTAyLTQ3NDg4LTc0MjE3MXJhbHVnZVJtb2MueWhwYXJnb3B5dCB8IG9DJkggKUMoIHRoZ2lyeXBvQ21vYy55aHBhcmdvcHl0Lnd3dy8vOnB0dGggLm9DICYgcmVsZmVvSCA3MDAyICw2MDAyIClDKCB0aGdpcnlwb0M/A0YAEgAJBAEAAwA/A0YAEQAJBAEAAwA/A0YAEAAJBAEAAwA/CVQADgAJBAEAAwBrBSIEDQAJBAEAAwA/CSQADAAJBAEAAwA/CSQACwAJBAEAAwBrBSIECgAJBAEAAwBRBRoACQAJBAEAAwBRBRoACAAJBAEAAwA/BD8ABwAJBAEAAwA/BAgABgAJBAEAAwBtBBoABQAJBAEAAwA/A0YABAAJBAEAAwArBEIAAwAJBAEAAwAdBA4AAgAJBAEAAwA/A0YAAQAJBAEAAwBXAz8AAAAJBAEAAwBAACMAEgAAAAAAAQBAACMAEQAAAAAAAQBAACMAEAAAAAAAAQAtAyoADgAAAAAAAQAKARECDQAAAAAAAQAbAxIADAAAAAAAAQAbAxIACwAAAAAAAQAKARECCgAAAAAAAQA/AA0ACQAAAAAAAQA/AA0ACAAAAAAAAQA/AGEABwAAAAAAAQA/AAQABgAAAAAAAQA/AA0ABQAAAAAAAQBAACMABAAAAAAAAQBqACEAAwAAAAAAAQBjAAcAAgAAAAAAAQBAACMAAQAAAAAAAQAAAEAAAAAAAAAAAQA/ASQAAAABACAAIAA/Aj8BAAAAAAsAAAA/AD8DPwA4PyADEj8kAAAAb0MmSAAAAAAAAAAASgAAUH8AAD8AAAAAAAAAAAAAAAA/ADIAPwEAAD8CPwI/AAAAPwI/AgQABQAsAU0CAgAAABsAAFAAABsAAAAAAAAAAAAAAAAAAAABAD8DAAAAAD8DAAAQPz8DAAABAAAAAAAAAAIACAAAACADPwM4PwAAHwIsPwAAAAAfAiw/AAAAAD8DCwA/PA9fPz8/LkEAAQAAAAEAIAAAAHgQAAAyAD8/dHNvcD8LAAA/AQAABDM1KGVtYW4GAAAAGAEAAABQGwBweGFtbAAAADAfAAA/Bj89eHRtaCQAAAA/AAAAAANhB2FlaGg2AAAAPwAAAD9HFgNkYWVoCAAAACgfAAALAAAAcHNhZzoDAAA8DQAAAj8/cGFtY2AAAAAgAQAASyU/VTIvU08gAAAACB8AAAQASABGRURHbw4AAD8QAABjPz9PIEZGQzAAAwA/AAsAT1RUTw==))); font-weight:300; font-style:normal; } @font-face{ font-family: "Gotham Rounded B"; src: url(data:font/opentype;base64,T1RUTwALAIAAAwAwQ0ZGIE+2i2MAABCYAAAOb0dERUYASAAEAAAfCAAAACBPUy8yVcclSwAAASAAAABgY21hcO62ywIAAA08AAADOmdhc3AAAAALAAAfKAAAAAhoZWFkAxZHvAAAALwAAAA2aGhlYQdhAwAAAAD0AAAAJGhtdHg9xwbVAAAfMAAAAGxtYXhwABtQAAAAARgAAAAGbmFtZSg1MwQAAAGAAAALu3Bvc3T/uAAyAAAQeAAAACAAAQAAAAEAQS6s5cVfDzz1AAsD6AAAAADQLAIfAAAAANAsAh8AAP84A58DIAAAAAgAAgAAAAAAAAABAAADwP8QAAAD1AAAAAADnwABAAAAAAAAAAAAAAAAAAAAGwAAUAAAGwAAAAICTQEsAAUABAK8AooAAACMArwCigAAAd0AMgD6AAAAAAAAAAAAAAAAoAAAf1AAAEoAAAAAAAAAAEgmQ28AAAAk4BIDIP84AMgDwADwAAAACwAAAAAB/gK8ACAAIAABAAAAJAG2AAEAAAAAAAAAQAAAAAEAAAAAAAEAIwBAAAEAAAAAAAIABwBjAAEAAAAAAAMAIQBqAAEAAAAAAAQAIwBAAAEAAAAAAAUADQCLAAEAAAAAAAYABACYAAEAAAAAAAcAYQCcAAEAAAAAAAgADQD9AAEAAAAAAAkADQD9AAEAAAAAAAoCEQEKAAEAAAAAAAsAEgMbAAEAAAAAAAwAEgMbAAEAAAAAAA0CEQEKAAEAAAAAAA4AKgMtAAEAAAAAABAAIwBAAAEAAAAAABEAIwBAAAEAAAAAABIAIwBAAAMAAQQJAAAAgANXAAMAAQQJAAEARgPXAAMAAQQJAAIADgQdAAMAAQQJAAMAQgQrAAMAAQQJAAQARgPXAAMAAQQJAAUAGgRtAAMAAQQJAAYACASHAAMAAQQJAAcAwgSPAAMAAQQJAAgAGgVRAAMAAQQJAAkAGgVRAAMAAQQJAAoEIgVrAAMAAQQJAAsAJAmNAAMAAQQJAAwAJAmNAAMAAQQJAA0EIgVrAAMAAQQJAA4AVAmxAAMAAQQJABAARgPXAAMAAQQJABEARgPXAAMAAQQJABIARgPXQ29weXJpZ2h0IChDKSAyMDA2LCAyMDA3IEhvZWZsZXIgJiBDby4gaHR0cDovL3d3dy50eXBvZ3JhcGh5LmNvbUNvcHlyaWdodCAoQykgSCZDbyB8IHR5cG9ncmFwaHkuY29tUmVndWxhcjE3MTI0Ny04ODQ3NC0yMDE1MDYyMy0yNDIzLTE0MDIxOVZlcnNpb24gMS4yMDFGb250R290aGFtIFJvdW5kZWQgaXMgYSB0cmFkZW1hcmsgb2YgSG9lZmxlciAmIENvLiwgd2hpY2ggbWF5IGJlIHJlZ2lzdGVyZWQgaW4gY2VydGFpbiBqdXJpc2RpY3Rpb25zLkhvZWZsZXIgJiBDby5UaGlzIHNvZnR3YXJlIGlzIHRoZSBwcm9wZXJ0eSBvZiBIb2VmbGVyICYgQ28uIFlvdSBtYXkgbm90IGNvcHksIG1vZGlmeSwgZGlzdHJpYnV0ZSwgb3IgZG93bmxvYWQgdGhpcyBzb2Z0d2FyZSwgb3IgaW5zdGFsbCBpdCB1cG9uIGFueSBjb21wdXRlciwgb3IgaG9zdCBpdCBmcm9tIGFueSBsb2NhdGlvbi4gWW91ciByaWdodCB0byB1c2UgdGhpcyBzb2Z0d2FyZSBpcyBzdWJqZWN0IHRvIHRoZSBUZXJtcyBvZiBTZXJ2aWNlIGFncmVlbWVudCB0aGF0IGV4aXN0cyBiZXR3ZWVuIHlvdSBhbmQgSG9lZmxlciAmIENvLiBJZiBubyBzdWNoIGFncmVlbWVudCBleGlzdHMsIHlvdSBtYXkgbm90IHVzZSB0aGlzIHNvZnR3YXJlIGZvciBhbnkgcHVycG9zZS4gRm9yIG1vcmUgaW5mb3JtYXRpb24sIHBsZWFzZSB2aXNpdCBodHRwOi8vd3d3LnR5cG9ncmFwaHkuY29tL3dlYmZvbnQtc29mdHdhcmUsIG9yIGNvbnRhY3QgSG9lZmxlciAmIENvLiBhdCB3d3cudHlwb2dyYXBoeS5jb20gMTcxMjQ3LTg4NDc0LTIwMTUwNjIzLTI0MjMtMTQwMjE5d3d3LnR5cG9ncmFwaHkuY29taHR0cDovL3d3dy50eXBvZ3JhcGh5LmNvbS93ZWJmb250LXNvZnR3YXJlAEMAbwBwAHkAcgBpAGcAaAB0ACAAKABDACkAIAAyADAAMAA2ACwAIAAyADAAMAA3ACAASABvAGUAZgBsAGUAcgAgACYAIABDAG8ALgAgAGgAdAB0AHAAOgAvAC8AdwB3AHcALgB0AHkAcABvAGcAcgBhAHAAaAB5AC4AYwBvAG0AQwBvAHAAeQByAGkAZwBoAHQAIAAoAEMAKQAgAEgAJgBDAG8AIAB8ACAAdAB5AHAAbwBnAHIAYQBwAGgAeQAuAGMAbwBtAFIAZQBnAHUAbABhAHIAMQA3ADEAMgA0ADcALQA4ADgANAA3ADQALQAyADAAMQA1ADAANgAyADMALQAyADQAMgAzAC0AMQA0ADAAMgAxADkAVgBlAHIAcwBpAG8AbgAgADEALgAyADAAMQBGAG8AbgB0AEcAbwB0AGgAYQBtACAAUgBvAHUAbgBkAGUAZAAgAGkAcwAgAGEAIAB0AHIAYQBkAGUAbQBhAHIAawAgAG8AZgAgAEgAbwBlAGYAbABlAHIAIAAmACAAQwBvAC4ALAAgAHcAaABpAGMAaAAgAG0AYQB5ACAAYgBlACAAcgBlAGcAaQBzAHQAZQByAGUAZAAgAGkAbgAgAGMAZQByAHQAYQBpAG4AIABqAHUAcgBpAHMAZABpAGMAdABpAG8AbgBzAC4ASABvAGUAZgBsAGUAcgAgACYAIABDAG8ALgBUAGgAaQBzACAAcwBvAGYAdAB3AGEAcgBlACAAaQBzACAAdABoAGUAIABwAHIAbwBwAGUAcgB0AHkAIABvAGYAIABIAG8AZQBmAGwAZQByACAAJgAgAEMAbwAuACAAWQBvAHUAIABtAGEAeQAgAG4AbwB0ACAAYwBvAHAAeQAsACAAbQBvAGQAaQBmAHkALAAgAGQAaQBzAHQAcgBpAGIAdQB0AGUALAAgAG8AcgAgAGQAbwB3AG4AbABvAGEAZAAgAHQAaABpAHMAIABzAG8AZgB0AHcAYQByAGUALAAgAG8AcgAgAGkAbgBzAHQAYQBsAGwAIABpAHQAIAB1AHAAbwBuACAAYQBuAHkAIABjAG8AbQBwAHUAdABlAHIALAAgAG8AcgAgAGgAbwBzAHQAIABpAHQAIABmAHIAbwBtACAAYQBuAHkAIABsAG8AYwBhAHQAaQBvAG4ALgAgAFkAbwB1AHIAIAByAGkAZwBoAHQAIAB0AG8AIAB1AHMAZQAgAHQAaABpAHMAIABzAG8AZgB0AHcAYQByAGUAIABpAHMAIABzAHUAYgBqAGUAYwB0ACAAdABvACAAdABoAGUAIABUAGUAcgBtAHMAIABvAGYAIABTAGUAcgB2AGkAYwBlACAAYQBnAHIA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); font-weight:300; font-style:normal; } \ No newline at end of file diff --git a/docs/static/fonts/332720/16C102A36B2DBC6E6.css b/docs/static/fonts/332720/16C102A36B2DBC6E6.css deleted file mode 100644 index 96c8c1f725..0000000000 --- a/docs/static/fonts/332720/16C102A36B2DBC6E6.css +++ /dev/null @@ -1,19 +0,0 @@ - -/* - Copyright (C) 2011-2015 Hoefler & Co. - This software is the property of Hoefler & Co. (H&Co). - Your right to access and use this software is subject to the - applicable License Agreement, or Terms of Service, that exists - between you and H&Co. If no such agreement exists, you may not - access or use this software for any purpose. - This software may only be hosted at the locations specified in - the applicable License Agreement or Terms of Service, and only - for the purposes expressly set forth therein. You may not copy, - modify, convert, create derivative works from or distribute this - software in any way, or make it accessible to any third party, - without first obtaining the written permission of H&Co. - For more information, please visit us at http://typography.com. - 171247-88474-20150623 -*/ - -@font-face{ font-family: "Gotham Rounded A"; src: url(data:font/opentype;base64,T1RUTwANAIAAAwBQQ0ZGILkPphQAABIUAAAk2kdERUYAkAAEAAA28AAAACBHUE9TuESiiwAANxAAABwCR1NVQunFLUgAAFMUAAAAgE9TLzJVxiUrAAABQAAAAGBjbWFw0U4uVAAADVwAAASYZ2FzcAAAAAsAAFOUAAAACGhlYWQDcke+AAAA3AAAADZoaGVhB74DqgAAARQAAAAkaG10eNbiGPsAAFOcAAABjG1heHAAY1AAAAABOAAAAAZuYW1lKDUzBAAAAaAAAAu7cG9zdP+4ADIAABH0AAAAIAABAAAAAQBBj0s7+V8PPPUACwPoAAAAANAsAh8AAAAA0CwCH//o/zgEEwMiAAAACAACAAAAAAAAAAEAAAPA/xAAAARO/+j/6AQTAAEAAAAAAAAAAAAAAAAAAABjAABQAABjAAAAAgIsASwABQAEArwCigAAAIwCvAKKAAAB3QAyAPoAAAAAAAAAAAAAAACgAAB/UAAASgAAAAAAAAAASCZDbwAAACPgEgMg/zgAyAPAAPAAAAALAAAAAAH+ArwAIAAgAAIAAAAkAbYAAQAAAAAAAABAAAAAAQAAAAAAAQAjAEAAAQAAAAAAAgAHAGMAAQAAAAAAAwAhAGoAAQAAAAAABAAjAEAAAQAAAAAABQANAIsAAQAAAAAABgAEAJgAAQAAAAAABwBhAJwAAQAAAAAACAANAP0AAQAAAAAACQANAP0AAQAAAAAACgIRAQoAAQAAAAAACwASAxsAAQAAAAAADAASAxsAAQAAAAAADQIRAQoAAQAAAAAADgAqAy0AAQAAAAAAEAAjAEAAAQAAAAAAEQAjAEAAAQAAAAAAEgAjAEAAAwABBAkAAACAA1cAAwABBAkAAQBGA9cAAwABBAkAAgAOBB0AAwABBAkAAwBCBCsAAwABBAkABABGA9cAAwABBAkABQAaBG0AAwABBAkABgAIBIcAAwABBAkABwDCBI8AAwABBAkACAAaBVEAAwABBAkACQAaBVEAAwABBAkACgQiBWsAAwABBAkACwAkCY0AAwABBAkADAAkCY0AAwABBAkADQQiBWsAAwABBAkADgBUCbEAAwABBAkAEABGA9cAAwABBAkAEQBGA9cAAwABBAkAEgBGA9dDb3B5cmlnaHQgKEMpIDIwMDYsIDIwMDcgSG9lZmxlciAmIENvLiBodHRwOi8vd3d3LnR5cG9ncmFwaHkuY29tQ29weXJpZ2h0IChDKSBIJkNvIHwgdHlwb2dyYXBoeS5jb21SZWd1bGFyMTcxMjQ3LTg4NDc0LTIwMTUwNjIzLTI0MjMtMTQwMjE5VmVyc2lvbiAxLjIwMUZvbnRHb3RoYW0gUm91bmRlZCBpcyBhIHRyYWRlbWFyayBvZiBIb2VmbGVyICYgQ28uLCB3aGljaCBtYXkgYmUgcmVnaXN0ZXJlZCBpbiBjZXJ0YWluIGp1cmlzZGljdGlvbnMuSG9lZmxlciAmIENvLlRoaXMgc29mdHdhcmUgaXMgdGhlIHByb3BlcnR5IG9mIEhvZWZsZXIgJiBDby4gWW91IG1heSBub3QgY29weSwgbW9kaWZ5LCBkaXN0cmlidXRlLCBvciBkb3dubG9hZCB0aGlzIHNvZnR3YXJlLCBvciBpbnN0YWxsIGl0IHVwb24gYW55IGNvbXB1dGVyLCBvciBob3N0IGl0IGZyb20gYW55IGxvY2F0aW9uLiBZb3VyIHJpZ2h0IHRvIHVzZSB0aGlzIHNvZnR3YXJlIGlzIHN1YmplY3QgdG8gdGhlIFRlcm1zIG9mIFNlcnZpY2UgYWdyZWVtZW50IHRoYXQgZXhpc3RzIGJldHdlZW4geW91IGFuZCBIb2VmbGVyICYgQ28uIElmIG5vIHN1Y2ggYWdyZWVtZW50IGV4aXN0cywgeW91IG1heSBub3QgdXNlIHRoaXMgc29mdHdhcmUgZm9yIGFueSBwdXJwb3NlLiBGb3IgbW9yZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpc2l0IGh0dHA6Ly93d3cudHlwb2dyYXBoeS5jb20vd2ViZm9udC1zb2Z0d2FyZSwgb3IgY29udGFjdCBIb2VmbGVyICYgQ28uIGF0IHd3dy50eXBvZ3JhcGh5LmNvbSAxNzEyNDctODg0NzQtMjAxNTA2MjMtMjQyMy0xNDAyMTl3d3cudHlwb2dyYXBoeS5jb21odHRwOi8vd3d3LnR5cG9ncmFwaHkuY29tL3dlYmZvbnQtc29mdHdhcmUAQwBvAHAAeQByAGkAZwBoAHQAIAAoAEMAKQAgADIAMAAwADYALAAgADIAMAAwADcAIABIAG8AZQBmAGwAZQByACAAJgAgAEMAbwAuACAAaAB0AHQAcAA6AC8ALwB3AHcAdwAuAHQAeQBwAG8AZwByAGEAcABoAHkALgBjAG8AbQBDAG8AcAB5AHIAaQBnAGgAdAAgACgAQwApACAASAAmAEMAbwAgAHwAIAB0AHkAcABvAGcAcgBhAHAAaAB5AC4AYwBvAG0AUgBlAGcAdQBsAGEAcgAxADcAMQAyADQANwAtADgAOAA0ADcANAAtADIAMAAxADUAMAA2ADIAMwAtADIANAAyADMALQAxADQAMAAyADEAOQBWAGUAcgBzAGkAbwBuACAAMQAuADIAMAAxAEYAbwBuAHQARwBvAHQAaABhAG0AIABSAG8AdQBuAGQAZQBkACAAaQBzACAAYQAgAHQAcgBhAGQAZQBtAGEAcgBrACAAbwBmACAASABvAGUAZgBsAGUAcgAgACYAIABDAG8ALgAsACAAdwBoAGkAYwBoACAAbQBhAHkAIABiAGUAIAByAGUAZwBpAHMAdABlAHIAZQBkACAAaQBuACAAYwBlAHIAdABhAGkAbgAgAGoAdQByAGkAcwBkAGkAYwB0AGkAbwBuAHMALgBIAG8AZQBmAGwAZQByACAAJgAgAEMAbwAuAFQAaABpAHMAIABzAG8AZgB0AHcAYQByAGUAIABpAHMAIAB0AGgAZQAgAHAAcgBvAHAAZQByAHQAeQAgAG8AZgAgAEgAbwBlAGYAbABlAHIAIAAmACAAQwBvAC4AIABZAG8AdQAgAG0AYQB5ACAAbgBvAHQAIABjAG8AcAB5ACwAIABtAG8AZABpAGYAeQAsACAAZABpAHMAdAByAGkAYgB1AHQAZQAsACAAbwByACAAZABvAHcAbgBsAG8AYQBkACAAdABoAGkAcwAgAHMAbwBmAHQAdwBhAHIAZQAsACAAbwByACAAaQBuAHMAdABhAGwAbAAgAGkAdAAgAHUAcABvAG4AIABhAG4AeQAgAGMAbwBtAHAAdQB0AGUAcgAsACAAbwByACAAaABvAHMAdAAgAGkAdAAgAGYAcgBvAG0AIABhAG4AeQAgAGwAbwBjAGEAdABpAG8AbgAuACAAWQBvAHUAcgAgAHIAaQBnAGgAdAAgAHQAbwAgAHUAcwBlACAAdABoAGkAcwAgAHMAbwBmAHQAdwBhAHIAZQAgAGkAcwAgAHMAdQBiAGoAZQBjAHQAIAB0AG8AIAB0AGgAZQAgAFQAZQByAG0AcwAgAG8AZgAgAFMAZQByAHYAaQBjAGUAIABhAGcAcgBlAGUAbQBlAG4AdAAgAHQAaABhAHQAIABlAHgAaQBzAHQAcwAgAGIAZQB0AHcAZQBlAG4AIAB5AG8AdQAgAGEAbgBkACAASABvAGUAZgBsAGUAcgAgACYAIABDAG8ALgAgAEkAZgAgAG4AbwAgAHMAdQBjAGgAIABhAGcAcgBlAGUAbQBlAG4AdAAgAGUAeABpAHMAdABzACwAIAB5AG8AdQAgAG0AYQB5ACAAbgBvAHQAIAB1AHMAZQAgAHQAaABpAHMAIABzAG8AZgB0AHcAYQByAGUAIABmAG8AcgAgAGEAbgB5ACAAcAB1AHIAcABvAHMAZQAuACAARgBvAHIAIABtAG8AcgBlACAAaQBuAGYAbwByAG0AYQB0AGkAbwBuACwAIABwAGwAZQBhAHMAZQAgAHYAaQBzAGkAdAAgAGgAdAB0AHAAOgAvAC8AdwB3AHcALgB0AHkAcABvAGcAcgBhAHAAaAB5AC4AYwBvAG0ALwB3AGUAYgBmAG8AbgB0AC0AcwBvAGYAdAB3AGEAcgBlACwAIABvAHIAIABjAG8AbgB0AGEAYwB0ACAASABvAGUAZgBsAGUAcgAgACYAIABDAG8ALgAgAGEAdAAgAHcAdwB3AC4AdAB5AHAAbwBnAHIAYQBwAGgAeQAuAGMAbwBtACAAMQA3ADEAMgA0ADcALQA4ADgANAA3ADQALQAyADAAMQA1ADAANgAyADMALQAyADQAMgAzAC0AMQA0ADAAMgAxADkAdwB3AHcALgB0AHkAcABvAGcAcgBhAHAAaAB5AC4AYwBvAG0AaAB0AHQAcAA6AC8ALwB3AHcAdwAuAHQAeQBwAG8AZwByAGEAcABoAHkALgBjAG8AbQAvAHcAZQBiAGYAbwBuAHQALQBzAG8AZgB0AHcAYQByAGUAAAAAAwAAAAMAAAAcAAEAAAAAA5IAAwABAAAAHAAEA3YAAACsAIAABgAsACAAIwAvADQANwA/AEQARwBNAF0AXwBjAHEAdAB2AHkAfQCjAKUAqwCuALAAtwC7AMUAxwDWAN0A5QDvAPYA+AD9AQcBDgEQARMBFQEXARkBGwEjAScBKwEtAS8BMQE3AUIBRAFGAUgBUQFUAVYBWAFaAV4BYAFlAWoBbAFuAXABcgF0AXkBewF9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/+cAAAAAAAAAAAAAAAD/8QAA/5z/9v+cAAAAAP/2AAD/8QAAAAAAAAAAAAAAAAAAAAAAFAAA//YAAAAAAAAAAAAAAAD/9gAA//H/8QAAAAAAAAAAAAAAAP/sAAD/7P/x//b/4gAAAAoAAAAAAAD/8QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/9gAAAAAAAAAAAAAAAAAAAAAAAAAA//sAAAAA//sAAAAAAAD/5wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//EAAP/xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/OAAD/9v/2//H/4v/iAAD/2AAA//b/9gAAAAAAAAAAAAD/4gAAAAD/5wAA/87/7P/n/+wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/+cAAP/s/8T/zgAA/84AAAAAAAAAAP/YAAAAAP+c/+z/jf+cAAD/fgAAAAD/9v+wAAD/iAAAAAD/9gAAAAD/+wAA/9j/7P/7AAAAAAAAAAAAAAAAAAD/xAAA/9j/2P+mAAAAAAAA/+wAAAAA/8T/zgAA/8QAAAAAAAD/2AAA/+L/+//JAAD/2P/d/87/xP/YAAAAAAAAAAD/2P/s/+wAAAAA/9gAAP/YAAAAAAAAAAAAAAAAAAAAAAAA/+L/7AAAAAAAAAAAAAAAAP/YAAAAAAAAAAAAAP/7AAAAAAAAAAD/ugAAAAAAAAAAAAAAAP/7AAD/9v/x//YAAAAAAAAAAAAAAAD/+wAA/5wAAP+cAAAADwAAAAoAAAAAAAAAAAAAAAAAAAAAAAAAFAAAAAAAAAAAAA8AAAAFAAAACgAAAAoAAAAAAAAAAAAAAAAAAP/JAAAAAP/dAAD/vwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//sAAP/2AAD/7P/xAAD/5wAAAAAAAAAAAAAAAAAAAAD/9gAAAAD/+wAAAAAACv/7AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAoAAAAAAAAAAAAAAAAAAAAAAAD/8QAAAAD/9v/xAAD/4v/n/+f/4v/2AAAAAAAAAAD/7AAAAAAAAAAAAAAAAAAAAAD/+wAAAAAAAAAAAAAAAAAAAAD/9gAAAAAAAAAAAAAAAAAA//sAAAAA//H/9v/x//H/+wAAAAD/pv/J/5L/8QAAAAAAAAAAAAAAAP/s/3n/ugAA/+wAAAAAAAD/ef/O/5z/g/+c/6b/zv+D/6b/uv/Y/9j/nAAAAAAAAAAAAAAAAAAA/40AAP+m/84AAP+c/5z/nP+c/5z/kgAAAAD/5wAA/+wAAAAAAAAAAAAA//YAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//EAAP/xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/xAAAAAAAAAAAAAP/7AAAAAAAAAAD/nP/YAAD/5wAAAAAAAP/2AAD/7P/2/7oAAAAA//YAAAAAAAD/uv/s/4j/v/+I/9j/5/+//8T/2P/sAAD/2AAAAAAAAAAAAAAAAAAA/8QAAAAA/+wAAP/YAAD/3QAA/9j/yQAAAAD/pv/d/5f/7AAAAAD/9v/2//H/7P/2/7r/0wAA//YAAAAAAAD/v//x/5z/xP+c/93/4v/E/87/3f/x//H/3QAAAAAAAAAAAAAAAAAA/8QAAP+c/+cAAP/d/93/3f/Y/93/yQAAAAAAAP/OAAD/4gAA//YAAP/xAAD/7AAA//YAAAAA//YAAAAAAAD/0wAAAAD/2AAA/87/7P/Y/87/7P/2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/+wAAP/sAAD/2AAA/9gAAAAAAAD/kv/E/37/3QAAAAD/7P/s/+wAAP/2/5z/ugAA//YAAAAAAAD/kv/Y/37/l/9+/7D/2P+X/5z/tf/s/+z/tQAAAAAAAAAAAAAAAAAA/5wAAP+S/+IAAP+1/8T/yf+6/8T/sAAAAAAAAP/YAAD/9gAAAAAAAAAAAAAAAP/2AAD/8QAAAAAAAAAAAAD/5wAAAAD/7AAA/+L/9v/s/+wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/+z/8QAA//EAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/xAAD/tQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/3QAAAAAAAAAAAAAAAAAA//sAAAAA/+z/7AAA/+wAAAAAAAAAAAAAAAD/9v+mAAAAAP/OAAD/ugAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/nAAAAAAAAAAAAAAAAAAAAAAAAAAA//YAAAAAAAAAAAAAAAD/7AAAAAD/8QAAAAAAAP/xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//YAAAAAAAoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/xAAD/uv/x/+wAAAAA//YAAP/2AAAAAAAAAAD/+wAAAAAAAAAA/+L/3QAA//YAAAAAAAAAAAAAAAAAAAAA/+f/7P/i/+f/8QAAAAAAAP/YAAAAAP+m//EAAP+cAAD/kgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/9gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/+IAAAAAAAD/xAAA/8QAAAAAAAAAAP/sAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/8QAAAAD/8QAAAAAAAP/2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//YAAAAAAAAAAAAAAAD/9gAA//b/9gAAAAAAAP/sAAAAAAAAAAAAAAAAAAAAAAAA//YAAAAAAAAAAAAAAAD/7AAAAAD/7AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//EAAAAAAAAAAAAAAAD/7AAA//YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/2AAAAAD/8QAAAAD/9gAAAAAAAP/2//YACgAAAAAAAAAA//H/8QAAAAoADwAAAAAAAAAAAAAAAAAA//v/+//2//sAAAAAAAAAAAAAAAAAAP/OAAD/7P/xAAD/2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/YAAAAAP+c//H/iP+cAAD/fgAAAAAAAAAAAAAAAAAAAAD/7AAAAAD/9gAAAAD/8f/2AAAAAAAAAA8AAP/OAAAAAAAAAAD/2AAAAAD/7AAA/+cAAAAA/6v/ugAA/9MAAP/sAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/sAAD/sP/2/+wAAAAA//YAAP/2AAAAAAAAAAAAAAAAAAAAAAAA/+L/2AAAAAAAAAAAAAAAAAAAAAAAAAAA/+f/5//i/+f/8QAAAAAAAP/YAAAAAP+c//H/iP+cAAD/fgAAAAAAAAAAAAAAAAAAAAD/7AAAAAD/9gAAAAD/8f/2AAAAAAAAAAAAAP/OAAAAAAAAAAD/2AAAAAD/7AAA/+cAAAAA/6v/ugAA/8QAAP/sAAD/2AAAAAAAAP+mAAD/2P/d/87/sP/iAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/iAAAAAAAAAAAAAAAAAAD/2AAAAAD/9gAA//H/9v/i//H/9gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//EAAAAeAAAAHgAeABT/9gAA/9P/9v/TAAAAAP/2//EAAAAAAAAAAAAAAB4AIwAAAB4AIwA3AAAAAP/TAAAAAAAAAAAAAAAAAAD/9gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/zgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP+6AAD/2P/d/+z/tQAAAAAAAAAAAAAAAAAAAAD/9gAAAAD/+wAAAAAAAP/7AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//H/9v/x//EAAAAAAAD/7AAAAAD/9v+mAAD/xP/O/87/nP/xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/9gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//YAAAAA//YAAAAA/+L/7P/T/+L/7AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/xAAD/tQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/4gAAAAAAAAAAAAAAAAAAAAAAAAAA/+z/8QAA//EAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//YAAAAAAAD/2AAAAAD/5wAAAAD/5wAA/+wAAP/n/+z/9gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//YAAP/2/+z/7AAA//EAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//YAAP/2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/sAAD/sP/x/+wAAAAA/+wAAP/sAAAAAAAAAAD/9gAAAAAAAAAA/+L/zgAA/+wAAAAAAAAAAAAAAAAAAAAA/+L/5//d/+L/7AAAAAAAAP/iAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/4gAAAAD/4gAAAAAAAP/sAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//EAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/sAAAAAP/E//EAAP/OAAD/ugAAAAoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/9gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//EAAAAAAAD/3QAA/90AAAAAAAD/pgAA/7AAAAAAAAAAAAAAAAAAAAAA//YAAAAAAAAAAAAAAAD/8QAAAAD/8QAAAAAAAP/xAAAAAAAAAAAAAAAAAAAAAP/dAAAAAAAA//YAAAAAAA8AAAAAAAAAAAAAAAD/9gAAAAD/nAAA/5wAAAAAAAAAAAAAAAAAAAAA/+wAAAAAAAAAAAAAAAD/0wAAAAD/2AAAAAAAAP/YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/+IAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/+cAAAAUAAD/4gAAAAD/5wAA/6b/5/+mAAAAAP/n//YAAAAAAAAAAAAAAAAAAAAAABQAIwAAAAAAAP+1AAAAAAAAAAAAAAAAAAD/9gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/tf/2//EAAAAAAAAAAAAAAAAAAAAA//YAAAAAAAAAAAAA/+z/3QAA//YAAAAA//YAAAAA//YAAAAA/+z/8f/n//H/9gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/5wAAP+c/+IAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/iP/YAAD/4gAAAAAAAAAAAAAAAP/s/78AAAAAAAAAAAAAAAD/sAAAAAD/ugAAAAD/5/+6AAAAAAAAAAD/zgAAAAAAAAAAAAAAAAAA/6sAAAAA/+wAAP/OAAD/zgAA/87/xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/2AAAAAD/8QAAAAD/8QAAAAAAAP/x//YAAAAAAAAAAAAAAAAAAAAAAAAACgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/zgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/+cAAAAAAAAAAAAAAAD/4gAA/6v/5/+r//EAAP/n/+L/8QAAAAAAAAAAAAAAAAAAAAAAAAAA/+wAAAAAAAAAAAAAAAD/8QAA//H/+wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/+wAAAAAAAD/zv/2/+z/5wAA/7r/7P+6//YAAP/s/+z/9gAAAAAAAAAAAAD/9gAAAAAAAAAA//EAAP/EAAAAAAAA//H/9v/2//b/+wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//EAAAAAAAAAAAAAAAD/3QAAAAD/4gAA/+IAAP/i/9P/8QAAAAAAAAAAAAAAAAAAAAAAAAAA/+wAAAAAAAAAAAAAAAD/9gAA//YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/+cAAAAAAAD/zv/2/+z/4gAA/6v/5/+r//EAAP/n/+L/8QAAAAAAAAAAAAD/9gAAAAAAAAAA/+wAAP+6AAAAAAAA//H/9v/2//b/+wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/0wAAAAD/8QAAAAD/8QAAAAAAAP/x//EAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/+wAAP/sAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEABQBbABgAAAAsAAAAGQAAACAAIwAiADMAAAAyAB8AHwAAAAAAAAAAAAEAAgADAAQABgAHAAgACQAKAAAACwAMAA0ADgAPABAAEQASABMAFAAVABYAHQAbAAAAAAAXABoAHgAhACQAJQAoAAAAAAApAAAAKAAoACsAGgAAADQANgA4ADkAHAAAAAAAAAAAAAAAAAAAACYAAAAAAAAAAAAnAC0AIwAjAC4ALwAgAC4ALwAgAAAAIgAmACcAAQAFAF0ADQAAAAAAIQAOAAAAFQAYABcAKQAAACgAFAAUAAAAAAAAACIAAQAAAAIAAAAAAAIAAwAAAAAAAAACAAAAAgAAAAQABQAGAAcACAAJAAoACwAAABAAEgAAAAwADwATABMAGQAaAA8AHQAeAA8ADwAfAB8AEwAfABYAKgAtAC8AMAAAAAAAEQAAAAAAAAAAAAAAGwAmAAAAAAAAABwAIwAYABgAJAAlABUAJAAlABUAAAAXABsAHAAAACYAAgAOAAUABQAAAAcABwABAAkACQACAAsADgADABAAEgAHABcAHwAKACEALgATADEANwAhADoAOgAoADwAPwApAEEARQAtAE0ATQAyAFIAWwAzAF0AXwA9AAEACAABAAAAAQABAAEAAAABAAAACgAwAD4AAkRGTFQADmxhdG4AGgAEAAAAAP//AAEAAAAEAAAAAP//AAEAAAABc3MwMQAIAAAAAQAAAAIABgAOAAYAAAABABAAAQAAAAEAKAABAAgAAQAOAAEAAQBiAAEABAABAGIAAQAAAAEAAAABAAEABv+fAAEAAQBiAAEAAf//AAoB9AAAASwAAAGaAEUCvAAtAzgANwK4ADEA5gBFAa4ARwGuADwBrgBMAmwAQADmADYBmABCAOYAUgH0//oCmAAvAksAQADwAFcA8AA7AmwAPAJsAE8CbABZAhYAJQMWADgC0gBoAuIASQMOAGgCkABoAxAASQIlACoCywBoAmsAaANkAGgDUgBJApwAaANSAEkC0wBoAoAAQQKIADIC+ABdAu4AOAROADwC0gBJAswANgKwAEcBrgBiAfQACQGuADcCWP/oAj4AMwKUAF0COwA6AkgAOgFqAC0ClAA8AmUAXQD5AF4A+f/7AjAAXQD5AGQDtwBdAmUAXQKAADoClABdApQAPAGQACoCRgA1AjoAQwJMADQB4AA3AR4AeQHgADUCRQA+AoQAQgKuADUDPgA1AYYAOgIDADcBoAAiAcIASgDmAFIBhgAvAgMAQwIWADQCEABCA4IAQgDmAE0A5gA7AOYANgGaAE0BmgA7AZoANgHWAG8CqABSATcANwE3AEMC0AA3ArIAFgK2ADI=); font-weight:300; font-style:normal; } @font-face{ font-family: "Gotham Rounded B"; src: url(data:font/opentype;base64,T1RUTwALAIAAAwAwQ0ZGIE+2i2MAABCYAAAOb0dERUYASAAEAAAfCAAAACBPUy8yVcclSwAAASAAAABgY21hcO62ywIAAA08AAADOmdhc3AAAAALAAAfKAAAAAhoZWFkAxZHvAAAALwAAAA2aGhlYQdhAwAAAAD0AAAAJGhtdHg9xwbVAAAfMAAAAGxtYXhwABtQAAAAARgAAAAGbmFtZSg1MwQAAAGAAAALu3Bvc3T/uAAyAAAQeAAAACAAAQAAAAEAQS6s5cVfDzz1AAsD6AAAAADQLAIfAAAAANAsAh8AAP84A58DIAAAAAgAAgAAAAAAAAABAAADwP8QAAAD1AAAAAADnwABAAAAAAAAAAAAAAAAAAAAGwAAUAAAGwAAAAICTQEsAAUABAK8AooAAACMArwCigAAAd0AMgD6AAAAAAAAAAAAAAAAoAAAf1AAAEoAAAAAAAAAAEgmQ28AAAAk4BIDIP84AMgDwADwAAAACwAAAAAB/gK8ACAAIAABAAAAJAG2AAEAAAAAAAAAQAAAAAEAAAAAAAEAIwBAAAEAAAAAAAIABwBjAAEAAAAAAAMAIQBqAAEAAAAAAAQAIwBAAAEAAAAAAAUADQCLAAEAAAAAAAYABACYAAEAAAAAAAcAYQCcAAEAAAAAAAgADQD9AAEAAAAAAAkADQD9AAEAAAAAAAoCEQEKAAEAAAAAAAsAEgMbAAEAAAAAAAwAEgMbAAEAAAAAAA0CEQEKAAEAAAAAAA4AKgMtAAEAAAAAABAAIwBAAAEAAAAAABEAIwBAAAEAAAAAABIAIwBAAAMAAQQJAAAAgANXAAMAAQQJAAEARgPXAAMAAQQJAAIADgQdAAMAAQQJAAMAQgQrAAMAAQQJAAQARgPXAAMAAQQJAAUAGgRtAAMAAQQJAAYACASHAAMAAQQJAAcAwgSPAAMAAQQJAAgAGgVRAAMAAQQJAAkAGgVRAAMAAQQJAAoEIgVrAAMAAQQJAAsAJAmNAAMAAQQJAAwAJAmNAAMAAQQJAA0EIgVrAAMAAQQJAA4AVAmxAAMAAQQJABAARgPXAAMAAQQJABEARgPXAAMAAQQJABIARgPXQ29weXJpZ2h0IChDKSAyMDA2LCAyMDA3IEhvZWZsZXIgJiBDby4gaHR0cDovL3d3dy50eXBvZ3JhcGh5LmNvbUNvcHlyaWdodCAoQykgSCZDbyB8IHR5cG9ncmFwaHkuY29tUmVndWxhcjE3MTI0Ny04ODQ3NC0yMDE1MDYyMy0yNDIzLTE0MDIxOVZlcnNpb24gMS4yMDFGb250R290aGFtIFJvdW5kZWQgaXMgYSB0cmFkZW1hcmsgb2YgSG9lZmxlciAmIENvLiwgd2hpY2ggbWF5IGJlIHJlZ2lzdGVyZWQgaW4gY2VydGFpbiBqdXJpc2RpY3Rpb25zLkhvZWZsZXIgJiBDby5UaGlzIHNvZnR3YXJlIGlzIHRoZSBwcm9wZXJ0eSBvZiBIb2VmbGVyICYgQ28uIFlvdSBtYXkgbm90IGNvcHksIG1vZGlmeSwgZGlzdHJpYnV0ZSwgb3IgZG93bmxvYWQgdGhpcyBzb2Z0d2FyZSwgb3IgaW5zdGFsbCBpdCB1cG9uIGFueSBjb21wdXRlciwgb3IgaG9zdCBpdCBmcm9tIGFueSBsb2NhdGlvbi4gWW91ciByaWdodCB0byB1c2UgdGhpcyBzb2Z0d2FyZSBpcyBzdWJqZWN0IHRvIHRoZSBUZXJtcyBvZiBTZXJ2aWNlIGFncmVlbWVudCB0aGF0IGV4aXN0cyBiZXR3ZWVuIHlvdSBhbmQgSG9lZmxlciAmIENvLiBJZiBubyBzdWNoIGFncmVlbWVudCBleGlzdHMsIHlvdSBtYXkgbm90IHVzZSB0aGlzIHNvZnR3YXJlIGZvciBhbnkgcHVycG9zZS4gRm9yIG1vcmUgaW5mb3JtYXRpb24sIHBsZWFzZSB2aXNpdCBodHRwOi8vd3d3LnR5cG9ncmFwaHkuY29tL3dlYmZvbnQtc29mdHdhcmUsIG9yIGNvbnRhY3QgSG9lZmxlciAmIENvLiBhdCB3d3cudHlwb2dyYXBoeS5jb20gMTcxMjQ3LTg4NDc0LTIwMTUwNjIzLTI0MjMtMTQwMjE5d3d3LnR5cG9ncmFwaHkuY29taHR0cDovL3d3dy50eXBvZ3JhcGh5LmNvbS93ZWJmb250LXNvZnR3YXJlAEMAbwBwAHkAcgBpAGcAaAB0ACAAKABDACkAIAAyADAAMAA2ACwAIAAyADAAMAA3ACAASABvAGUAZgBsAGUAcgAgACYAIABDAG8ALgAgAGgAdAB0AHAAOgAvAC8AdwB3AHcALgB0AHkAcABvAGcAcgBhAHAAaAB5AC4AYwBvAG0AQwBvAHAAeQByAGkAZwBoAHQAIAAoAEMAKQAgAEgAJgBDAG8AIAB8ACAAdAB5AHAAbwBnAHIAYQBwAGgAeQAuAGMAbwBtAFIAZQBnAHUAbABhAHIAMQA3ADEAMgA0ADcALQA4ADgANAA3ADQALQAyADAAMQA1ADAANgAyADMALQAyADQAMgAzAC0AMQA0ADAAMgAxADkAVgBlAHIAcwBpAG8AbgAgADEALgAyADAAMQBGAG8AbgB0AEcAbwB0AGgAYQBtACAAUgBvAHUAbgBkAGUAZAAgAGkAcwAgAGEAIAB0AHIAYQBkAGUAbQBhAHIAawAgAG8AZgAgAEgAbwBlAGYAbABlAHIAIAAmACAAQwBvAC4ALAAgAHcAaABpAGMAaAAgAG0AYQB5ACAAYgBlACAAcgBlAGcAaQBzAHQAZQByAGUAZAAgAGkAbgAgAGMAZQByAHQAYQBpAG4AIABqAHUAcgBpAHMAZABpAGMAdABpAG8AbgBzAC4ASABvAGUAZgBsAGUAcgAgACYAIABDAG8ALgBUAGgAaQBzACAAcwBvAGYAdAB3AGEAcgBlACAAaQBzACAAdABoAGUAIABwAHIAbwBwAGUAcgB0AHkAIABvAGYAIABIAG8AZQBmAGwAZQByACAAJgAgAEMAbwAuACAAWQBvAHUAIABtAGEAeQAgAG4AbwB0ACAAYwBvAHAAeQAsACAAbQBvAGQAaQBmAHkALAAgAGQAaQBzAHQAcgBpAGIAdQB0AGUALAAgAG8AcgAgAGQAbwB3AG4AbABvAGEAZAAgAHQAaABpAHMAIABzAG8AZgB0AHcAYQByAGUALAAgAG8AcgAgAGkAbgBzAHQAYQBsAGwAIABpAHQAIAB1AHAAbwBuACAAYQBuAHkAIABjAG8AbQBwAHUAdABlAHIALAAgAG8AcgAgAGgAbwBzAHQAIABpAHQAIABmAHIAbwBtACAAYQBuAHkAIABsAG8AYwBhAHQAaQBvAG4ALgAgAFkAbwB1AHIAIAByAGkAZwBoAHQAIAB0AG8AIAB1AHMAZQAgAHQAaABpAHMAIABzAG8AZgB0AHcAYQByAGUAIABpAHMAIABzAHUAYgBqAGUAYwB0ACAAdABvACAAdABoAGUAIABUAGUAcgBtAHMAIABvAGYAIABTAGUAcgB2AGkAYwBlACAAYQBnAHIA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); font-weight:300; font-style:normal; } \ No newline at end of file diff --git a/docs/static/fonts/332720/21FF71D0D2122923F.css b/docs/static/fonts/332720/21FF71D0D2122923F.css deleted file mode 100644 index 1251976746..0000000000 --- a/docs/static/fonts/332720/21FF71D0D2122923F.css +++ /dev/null @@ -1,19 +0,0 @@ - -/* - Copyright (C) 2011-2015 Hoefler & Co. - This software is the property of Hoefler & Co. (H&Co). - Your right to access and use this software is subject to the - applicable License Agreement, or Terms of Service, that exists - between you and H&Co. If no such agreement exists, you may not - access or use this software for any purpose. - This software may only be hosted at the locations specified in - the applicable License Agreement or Terms of Service, and only - for the purposes expressly set forth therein. You may not copy, - modify, convert, create derivative works from or distribute this - software in any way, or make it accessible to any third party, - without first obtaining the written permission of H&Co. - For more information, please visit us at http://typography.com. - 171247-88474-20150623 -*/ - -@font-face{ font-family: "Gotham Rounded A"; src: url(data:font/truetype;base64,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LiBGb3IgbW9yZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpc2l0IGh0dHA6Ly93d3cudHlwb2dyYXBoeS5jb20vd2ViZm9udC1zb2Z0d2FyZSwgb3IgY29udGFjdCBIb2VmbGVyICYgQ28uIGF0IHd3dy50eXBvZ3JhcGh5LmNvbSAxNzEyNDctODg0NzQtMjAxNTA2MjMtMjQyMy0xNDAyMTl3d3cudHlwb2dyYXBoeS5jb21odHRwOi8vd3d3LnR5cG9ncmFwaHkuY29tL3dlYmZvbnQtc29mdHdhcmUAQwBvAHAAeQByAGkAZwBoAHQAIAAoAEMAKQAgADIAMAAwADYALAAgADIAMAAwADcAIABIAG8AZQBmAGwAZQByACAAJgAgAEMAbwAuACAAaAB0AHQAcAA6AC8ALwB3AHcAdwAuAHQAeQBwAG8AZwByAGEAcABoAHkALgBjAG8AbQBDAG8AcAB5AHIAaQBnAGgAdAAgACgAQwApACAASAAmAEMAbwAgAHwAIAB0AHkAcABvAGcAcgBhAHAAaAB5AC4AYwBvAG0AUgBlAGcAdQBsAGEAcgAxADcAMQAyADQANwAtADgAOAA0ADcANAAtADIAMAAxADUAMAA2ADIAMwAtADIANAAyADMALQAxADQAMAAyADEAOQBWAGUAcgBzAGkAbwBuACAAMQAuADMAMAAxAEYAbwBuAHQARwBvAHQAaABhAG0AIABpAHMAIABhACAAdAByAGEAZABlAG0AYQByAGsAIABvAGYAIABIAG8AZQBmAGwAZQByACAAJgAgAEMAbwAuACwAIAB3AGgAaQBjAGgAIABtAGEAeQAgAGIAZQAgAHIAZQBnAGkAcwB0AGUAcgBlAGQAIABpAG4AIABjAGUAcgB0AGEAaQBuACAAagB1AHIAaQBzAGQAaQBjAHQAaQBvAG4AcwAuAEgAbwBlAGYAbABlAHIAIAAmACAAQwBvAC4AVABoAGkAcwAgAHMAbwBmAHQAdwBhAHIAZQAgAGkAcwAgAHQAaABlACAAcAByAG8AcABlAHIAdAB5ACAAbwBmACAASABvAGUAZgBsAGUAcgAgACYAIABDAG8ALgAgAFkAbwB1ACAAbQBhAHkAIABuAG8AdAAgAGMAbwBwAHkALAAgAG0AbwBkAGkAZgB5ACwAIABkAGkAcwB0AHIAaQBiAHUAdABlACwAIABvAHIAIABkAG8AdwBuAGwAbwBhAGQAIAB0AGgAaQBzACAAcwBvAGYAdAB3AGEAcgBlACwAIABvAHIAIABpAG4AcwB0AGEAbABsACAAaQB0ACAAdQBwAG8AbgAgAGEAbgB5ACAAYwBvAG0AcAB1AHQAZQByACwAIABvAHIAIABoAG8AcwB0ACAAaQB0ACAAZgByAG8AbQAgAGEAbgB5ACAAbABvAGMAYQB0AGkAbwBuAC4AIABZAG8AdQByACAAcgBpAGcAaAB0ACAAdABvACAAdQBzAGUAIAB0AGgAaQBzACAAcwBvAGYAdAB3AGEAcgBlACAAaQBzACAAcwB1AGIAagBlAGMAdAAgAHQAbwAgAHQAaABlACAAVABlAHIAbQBzACAAbwBmACAAUwBlAHIAdgBpAGMAZQAgAGEAZwByAGUAZQBtAGUAbgB0ACAAdABoAGEAdAAgAGUAeABpAHMAdABzACAAYgBlAHQAdwBlAGUAbgAgAHkAbwB1ACAAYQBuAGQAIABIAG8AZQBmAGwAZQByACAAJgAgAEMAbwAuACAASQBmACAAbgBvACAAcwB1AGMAaAAgAGEAZwByAGUAZQBtAGUAbgB0ACAAZQB4AGkAcwB0AHMALAAgAHkAbwB1ACAAbQBhAHkAIABuAG8AdAAgAHUAcwBlACAAdABoAGkAcwAgAHMAbwBmAHQAdwBhAHIAZQAgAGYAbwByACAAYQBuAHkAIABwAHUAcgBwAG8AcwBlAC4AIABGAG8AcgAgAG0AbwByAGUAIABpAG4AZgBvAHIAbQBhAHQAaQBvAG4ALAAgAHAAbABlAGEAcwBlACAAdgBpAHMAaQB0ACAAaAB0AHQAcAA6AC8ALwB3AHcAdwAuAHQAeQBwAG8AZwByAGEAcABoAHkALgBjAG8AbQAvAHcAZQBiAGYAbwBuAHQALQBzAG8AZgB0AHcAYQByAGUALAAgAG8AcgAgAGMAbwBuAHQAYQBjAHQAIABIAG8AZQBmAGwAZQByACAAJgAgAEMAbwAuACAAYQB0ACAAdwB3AHcALgB0AHkAcABvAGcAcgBhAHAAaAB5AC4AYwBvAG0AIAAxADcAMQAyADQANwAtADgAOAA0ADcANAAtADIAMAAxADUAMAA2ADIAMwAtADIANAAyADMALQAxADQAMAAyADEAOQB3AHcA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AAAAAAAAAAAAAAAAAAD/9gAAAAD/9gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//b/9gAA//YAAAAAAAD/sP/sAAAAAAAAAAAAAAAAAAAAAP/2/+cAAAAAAAAAAAAAAAD/8QAA/5z/9v+cAAAAAP/2AAD/8QAAAAAAAAAAAAAAAAAAAAAAFAAA//YAAAAAAAAAAAAAAAD/9gAA//H/8QAAAAAAAAAAAAAAAP/sAAD/7P/x//b/4gAAAAoAAAAAAAD/8QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/9gAAAAAAAAAAAAAAAAAAAAAAAAAA//sAAAAA//sAAAAAAAD/5wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//EAAP/xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/OAAD/9v/2//H/4v/iAAD/2AAA//b/9gAAAAAAAAAAAAD/4gAAAAD/5wAA/87/7P/n/+wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/+cAAP/s/8T/zgAA/84AAAAAAAAAAP/YAAAAAP+c/+z/jf+cAAD/fgAAAAD/9v+wAAD/iAAAAAD/9gAAAAD/+wAA/9j/7P/7AAAAAAAAAAAAAAAAAAD/xAAA/9j/2P+mAAAAAAAA/+wAAAAA/8T/zgAA/8QAAAAAAAD/2AAA/+L/+//JAAD/2P/d/87/xP/YAAAAAAAAAAD/2P/s/+wAAAAA/9gAAP/YAAAAAAAAAAAAAAAAAAAAAAAA/+L/7AAAAAAAAAAAAAAAAP/YAAAAAAAAAAAAAP/7AAAAAAAAAAD/ugAAAAAAAAAAAAAAAP/7AAD/9v/x//YAAAAAAAAAAAAAAAD/+wAA/5wAAP+cAAAADwAAAAoAAAAAAAAAAAAAAAAAAAAAAAAAFAAAAAAAAAAAAA8AAAAFAAAACgAAAAoAAAAAAAAAAAAAAAAAAP/JAAAAAP/dAAD/vwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//sAAP/2AAD/7P/xAAD/5wAAAAAAAAAAAAAAAAAAAAD/9gAAAAD/+wAAAAAACv/7AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAoAAAAAAAAAAAAAAAAAAAAAAAD/8QAAAAD/9v/xAAD/4v/n/+f/4v/2AAAAAAAAAAD/7AAAAAAAAAAAAAAAAAAAAAD/+wAAAAAAAAAAAAAAAAAAAAD/9gAAAAAAAAAAAAAAAAAA//sAAAAA//H/9v/x//H/+wAAAAD/pv/J/5L/8QAAAAAAAAAAAAAAAP/s/3n/ugAA/+wAAAAAAAD/ef/O/5z/g/+c/6b/zv+D/6b/uv/Y/9j/nAAAAAAAAAAAAAAAAAAA/40AAP+m/84AAP+c/5z/nP+c/5z/kgAAAAD/5wAA/+wAAAAAAAAAAAAA//YAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//EAAP/xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/xAAAAAAAAAAAAAP/7AAAAAAAAAAD/nP/YAAD/5wAAAAAAAP/2AAD/7P/2/7oAAAAA//YAAAAAAAD/uv/s/4j/v/+I/9j/5/+//8T/2P/sAAD/2AAAAAAAAAAAAAAAAAAA/8QAAAAA/+wAAP/YAAD/3QAA/9j/yQAAAAD/pv/d/5f/7AAAAAD/9v/2//H/7P/2/7r/0wAA//YAAAAAAAD/v//x/5z/xP+c/93/4v/E/87/3f/x//H/3QAAAAAAAAAAAAAAAAAA/8QAAP+c/+cAAP/d/93/3f/Y/93/yQAAAAAAAP/OAAD/4gAA//YAAP/xAAD/7AAA//YAAAAA//YAAAAAAAD/0wAAAAD/2AAA/87/7P/Y/87/7P/2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/+wAAP/sAAD/2AAA/9gAAAAAAAD/kv/E/37/3QAAAAD/7P/s/+wAAP/2/5z/ugAA//YAAAAAAAD/kv/Y/37/l/9+/7D/2P+X/5z/tf/s/+z/tQAAAAAAAAAAAAAAAAAA/5wAAP+S/+IAAP+1/8T/yf+6/8T/sAAAAAAAAP/YAAD/9gAAAAAAAAAAAAAAAP/2AAD/8QAAAAAAAAAAAAD/5wAAAAD/7AAA/+L/9v/s/+wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/+z/8QAA//EAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/xAAD/tQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/3QAAAAAAAAAAAAAAAAAA//sAAAAA/+z/7AAA/+wAAAAAAAAAAAAAAAD/9v+mAAAAAP/OAAD/ugAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/nAAAAAAAAAAAAAAAAAAAAAAAAAAA//YAAAAAAAAAAAAAAAD/7AAAAAD/8QAAAAAAAP/xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//YAAAAAAAoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/xAAD/uv/x/+wAAAAA//YAAP/2AAAAAAAAAAD/+wAAAAAAAAAA/+L/3QAA//YAAAAAAAAAAAAAAAAAAAAA/+f/7P/i/+f/8QAAAAAAAP/YAAAAAP+m//EAAP+cAAD/kgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/9gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/+IAAAAAAAD/xAAA/8QAAAAAAAAAAP/sAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/8QAAAAD/8QAAAAAAAP/2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//YAAAAAAAAAAAAAAAD/9gAA//b/9gAAAAAAAP/sAAAAAAAAAAAAAAAAAAAAAAAA//YAAAAAAAAAAAAAAAD/7AAAAAD/7AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//EAAAAAAAAAAAAAAAD/7AAA//YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/2AAAAAD/8QAAAAD/9gAAAAAAAP/2//YACgAAAAAAAAAA//H/8QAAAAoADwAAAAAAAAAAAAAAAAAA//v/+//2//sAAAAAAAAAAAAAAAAAAP/OAAD/7P/xAAD/2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/YAAAAAP+c//H/iP+cAAD/fgAAAAAAAAAAAAAAAAAAAAD/7AAAAAD/9gAAAAD/8f/2AAAAAAAAAA8AAP/OAAAAAAAAAAD/2AAAAAD/7AAA/+cAAAAA/6v/ugAA/9MAAP/sAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/sAAD/sP/2/+wAAAAA//YAAP/2AAAAAAAAAAAAAAAAAAAAAAAA/+L/2AAAAAAAAAAAAAAAAAAAAAAAAAAA/+f/5//i/+f/8QAAAAAAAP/YAAAAAP+c//H/iP+cAAD/fgAAAAAAAAAAAAAAAAAAAAD/7AAAAAD/9gAAAAD/8f/2AAAAAAAAAAAAAP/OAAAAAAAAAAD/2AAAAAD/7AAA/+cAAAAA/6v/ugAA/8QAAP/sAAD/2AAAAAAAAP+mAAD/2P/d/87/sP/iAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/iAAAAAAAAAAAAAAAAAAD/2AAAAAD/9gAA//H/9v/i//H/9gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//EAAAAeAAAAHgAeABT/9gAA/9P/9v/TAAAAAP/2//EAAAAAAAAAAAAAAB4AIwAAAB4AIwA3AAAAAP/TAAAAAAAAAAAAAAAAAAD/9gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/zgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP+6AAD/2P/d/+z/tQAAAAAAAAAAAAAAAAAAAAD/9gAAAAD/+wAAAAAAAP/7AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//H/9v/x//EAAAAAAAD/7AAAAAD/9v+mAAD/xP/O/87/nP/xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/9gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//YAAAAA//YAAAAA/+L/7P/T/+L/7AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/xAAD/tQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/4gAAAAAAAAAAAAAAAAAAAAAAAAAA/+z/8QAA//EAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//YAAAAAAAD/2AAAAAD/5wAAAAD/5wAA/+wAAP/n/+z/9gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//YAAP/2/+z/7AAA//EAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//YAAP/2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/sAAD/sP/x/+wAAAAA/+wAAP/sAAAAAAAAAAD/9gAAAAAAAAAA/+L/zgAA/+wAAAAAAAAAAAAAAAAAAAAA/+L/5//d/+L/7AAAAAAAAP/iAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/4gAAAAD/4gAAAAAAAP/sAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//EAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/sAAAAAP/E//EAAP/OAAD/ugAAAAoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/9gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//EAAAAAAAD/3QAA/90AAAAAAAD/pgAA/7AAAAAAAAAAAAAAAAAAAAAA//YAAAAAAAAAAAAAAAD/8QAAAAD/8QAAAAAAAP/xAAAAAAAAAAAAAAAAAAAAAP/dAAAAAAAA//YAAAAAAA8AAAAAAAAAAAAAAAD/9gAAAAD/nAAA/5wAAAAAAAAAAAAAAAAAAAAA/+wAAAAAAAAAAAAAAAD/0wAAAAD/2AAAAAAAAP/YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/+IAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/+cAAAAUAAD/4gAAAAD/5wAA/6b/5/+mAAAAAP/n//YAAAAAAAAAAAAAAAAAAAAAABQAIwAAAAAAAP+1AAAAAAAAAAAAAAAAAAD/9gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/tf/2//EAAAAAAAAAAAAAAAAAAAAA//YAAAAAAAAAAAAA/+z/3QAA//YAAAAA//YAAAAA//YAAAAA/+z/8f/n//H/9gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/5wAAP+c/+IAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/iP/YAAD/4gAAAAAAAAAAAAAAAP/s/78AAAAAAAAAAAAAAAD/sAAAAAD/ugAAAAD/5/+6AAAAAAAAAAD/zgAAAAAAAAAAAAAAAAAA/6sAAAAA/+wAAP/OAAD/zgAA/87/xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/2AAAAAD/8QAAAAD/8QAAAAAAAP/x//YAAAAAAAAAAAAAAAAAAAAAAAAACgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/zgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/+cAAAAAAAAAAAAAAAD/4gAA/6v/5/+r//EAAP/n/+L/8QAAAAAAAAAAAAAAAAAAAAAAAAAA/+wAAAAAAAAAAAAAAAD/8QAA//H/+wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/+wAAAAAAAD/zv/2/+z/5wAA/7r/7P+6//YAAP/s/+z/9gAAAAAAAAAAAAD/9gAAAAAAAAAA//EAAP/EAAAAAAAA//H/9v/2//b/+wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//EAAAAAAAAAAAAAAAD/3QAAAAD/4gAA/+IAAP/i/9P/8QAAAAAAAAAAAAAAAAAAAAAAAAAA/+wAAAAAAAAAAAAAAAD/9gAA//YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/+cAAAAAAAD/zv/2/+z/4gAA/6v/5/+r//EAAP/n/+L/8QAAAAAAAAAAAAD/9gAAAAAAAAAA/+wAAP+6AAAAAAAA//H/9v/2//b/+wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/0wAAAAD/8QAAAAD/8QAAAAAAAP/x//EAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/+wAAP/sAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEACQBvABgAAAAsAAAAGQAAACAAIwAiADMAOwAAAAAAAAAAAAAAAAAyAAAAKgAfAB8AAAAAAAAAAAAAAAEAAgADAAQABQAGAAcAAAAAAAgACQAKAAAAAAALAAwADQAOAA8AEAARABIAEwAUABUAFgAdABsAAAAAABcAGgAeAAAAIQAkACUAKAAAAAAAKQAAACgAKAArABoAAAAwADEANAA1ADYANwA4ADkAOgAcAAAAAAAAAAAAAAAAAAAAAAAmAAAAAAAAAAAAJwAtACMAIwAuAC8AIAAuAC8AIAAAACIAJgAnAAEACQBxAA0AAAAAACEADgAAABUAGAAXACkAMgAgAAAAKwAAAAAAAAAoAAAAAAAUABQAAAAAAAAAIgAAAAEAAAACAAAAAAAAAAIAAAAAAAMAAAAAAAAAAAACAAAAAgAAAAQABQAGAAcACAAJAAoACwAAABAAEgAAAAwADwATABYAEwAZABoADwAdAB4ADwAPAB8AHwATAB8AFgAfACcAKgAsAC0ALgAvADAAMQAAAAAAEQAAAAAAAAAAAAAAAAAbACYAAAAAAAAAHAAjABgAGAAkACUAFQAkACUAFQAAABcAGwAcAAAAJgACABEACQAJAAAACwALAAEADQANAAIADwATAAMAGgAaAAgAHAAeAAkAJAAqAAwALQAvABMAMgA/ABYAQgBEACQARgBJACcATABMACsATgBRACwAUwBcADAAZQBlADoAagBzADsAdQB3AEUAAQAIAAEAAAABAAEAAwAAAAEAAAAKADAAPgACREZMVAAObGF0bgAaAAQAAAAA//8AAQAAAAQAAAAA//8AAQAAAAFzczAxAAgAAAABAAAAAgAGAA4ABgAAAAEAEAABAAAAAQAoAAEACAABAA4AAQABAHoAAQAEAAEAegABAAAAAQAAAAEAAQAG/4kAAQABAHo=); font-weight:300; font-style:normal; } \ No newline at end of file diff --git a/docs/static/fonts/332720/2C6F673F0C1CF0A97.css b/docs/static/fonts/332720/2C6F673F0C1CF0A97.css deleted file mode 100644 index 1eb5423b53..0000000000 --- a/docs/static/fonts/332720/2C6F673F0C1CF0A97.css +++ /dev/null @@ -1,19 +0,0 @@ - -/* - Copyright (C) 2011-2015 Hoefler & Co. - This software is the property of Hoefler & Co. (H&Co). - Your right to access and use this software is subject to the - applicable License Agreement, or Terms of Service, that exists - between you and H&Co. If no such agreement exists, you may not - access or use this software for any purpose. - This software may only be hosted at the locations specified in - the applicable License Agreement or Terms of Service, and only - for the purposes expressly set forth therein. You may not copy, - modify, convert, create derivative works from or distribute this - software in any way, or make it accessible to any third party, - without first obtaining the written permission of H&Co. - For more information, please visit us at http://typography.com. - 171247-88474-20150623 -*/ - -@font-face{ font-family: "Gotham Rounded A"; src: url(data:application/x-font-woff;base64,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))); font-weight:300; font-style:normal; } @font-face{ font-family: "Gotham Rounded B"; src: url(data:application/x-font-woff;base64,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); font-weight:300; font-style:normal; } \ No newline at end of file diff --git a/docs/static/fonts/332720/3919129618BB6AFD8.css b/docs/static/fonts/332720/3919129618BB6AFD8.css deleted file mode 100644 index ceb4caa3b8..0000000000 --- a/docs/static/fonts/332720/3919129618BB6AFD8.css +++ /dev/null @@ -1,19 +0,0 @@ - -/* - Copyright (C) 2011-2015 Hoefler & Co. - This software is the property of Hoefler & Co. (H&Co). - Your right to access and use this software is subject to the - applicable License Agreement, or Terms of Service, that exists - between you and H&Co. If no such agreement exists, you may not - access or use this software for any purpose. - This software may only be hosted at the locations specified in - the applicable License Agreement or Terms of Service, and only - for the purposes expressly set forth therein. You may not copy, - modify, convert, create derivative works from or distribute this - software in any way, or make it accessible to any third party, - without first obtaining the written permission of H&Co. - For more information, please visit us at http://typography.com. - 171247-88474-20150623 -*/ - -@font-face{ font-family: "Gotham Rounded A"; src: url(data:application/x-font-woff;base64,S0EpP18/Wj89PDM/GT8/PzA/H3p5Jz8/VD8/Wm8/Cx1kP2w/Pz8PP3cOCD9DIz8/XQJyCj9ZPwUzQz9IPz98NEtxIz8/LUQ/Pz8/TyE/Pz8zPz8yYj8/Pxo/aj9OH1g/PT8fJUscPyE/azw/Zz8hP04/LkV+Rz95T1R4EFM/M3k/YD9Waxw/P0w/P2A/ATckem0/P0NNCz8/Ex5LOj8PA1JiPzl1Dj8ZPT8/Pz4/Zj8VPz8MPzA/GiE/Pz8/Ez8BFj8/NGohPz8UFz0/Kz9APz9BP30/Pw0/Pz8lPxM/Pz8EAz8/OB0/P0UqG1o9Iz8/GHw/dXZbSxk/PwZLWgFQGmg/KTRkFHk/Pz86Pz9gEz9tTg8/Lj9ZPz8Cfj8lAD8/aC1OPxI/Pz9zVT9wFUA/Lj8jPxE/cz9PPw8rU2I/DhM/VT0/TD8/acg/NT48aD9GP0c/Pz91Py0/SXU/aT9gP1RVP0EfQT9fGHQ5XAM/Pz9UP0Q/Kj9CMDkkaD8/Py4/bD8/Pz8/Jj9FPz8/P2ceYj8/Pz9sPxY/P1BJUWw/Rj8/aT8/PykIMT9FPz8/LxVzbT9VPzI/Pz8BGmQ/RVk/XnR7A3VvLz8/fT8/P2o/SRc/P20JA2kNPz8/cT8hWlg/HWsVHA4QP0A/ZD0/AE0JPxMwMD47FT8/EDA/cj9VPz94AF5oP38APz9zPz8/P3M5MD9MZwk/Pz8/JCJHImg/P0Q/eT9IXDs/Dj8/Pz85P2s/P2M/Pz8aPwg/ei0lIT8/PyU/Pz9QP25UPz1MRT8/FklMLT9sez8/BT8/PwETPz8/Pz8/P3k/Xj8/PzI/e3QVPz9hVz8zGj8/Pyo1FgRvQHICOD97Pz8/Pxg6Pz9yQh0/Pz8HP3c/cz8/KSI/Pw8/P38/KQYmXj8/Pz8rP00/NRULP2QuP1E/Pz8QP2QXP1E/Pz8/BEc/Pxg/FD9HcD8iP1U/Wyc/CRVKPz8/OD8/DyU/BVQ/bls/Tj8tRSBqPz8/QD9ZJRIZPz8rPz8/KT8dMRtlRhU/SD8/Pz8BPz86Pz9yPzs/OXc/Pz8/FT9RTRA/PxYQPz81NDVDRD9jREg/Qz9ISFtRbQVIGD9eGj8/Hz8/Pz8/PD9NKjEXAh0bP0hLS257PxRRQkg/Py0/eAoAPz8BAAEAAABHDHk/ACw/Tj8DIzFAM0oFPz8qGRk/Dz8/OT8DQT9EAD8gPwc/Pz9AWD9wMhgbFxYzZkc/AD8/PzM/AWBiP2M/LEk/P2EJP3FyYGM/YDBiP2BgZGBjP3gAP0g/PxQnPz8/Pz9LfQY/Fz8/Tz8/cVcYGXQ7Pz8/P10yPwY/PzU/P3oLOmU/PzM/HFwYfUh2PyF7IxpiPwN5Pz8AO2AgPz8/PydyFwUZeD9mazdyal4/Kxo/Kz80Pyh3cT8/Nz8/Pz9LPwh6PwA/Am0TPz8/fj8+P2E/Pz9oEz8/GBoJPwIyAg8/Pw0CP3U1P3s/Pz8+Pz8/Sz8/RVBxPz8/Zx0/Eng/Q3o/DT8/UiMfPyc/AkI/Qjo+Pz8/QDp8Pz9wP000Pz8/dz9HPz96ST8/P3RGMT9xB2g/P2QdFD8/T3s/F2knPz8/Pz9YP38/Zz8hPztpBm8/bT8ZDCQ/Pz8/ej9cPz8PaGc/cT8EPydLP0RFP0I/Qh08JUV9P1E/Pz9PJwc/LT8/P0tiPz88Pz8jPz8sahssP08PFGM/OyE/P0I2P10/P3I/Pzs/Pz8/LHJiJj86PydWPz8/Pz8bKD8/eTs/Pz97Pz8eRQtpPz8/C2Y/dxk7Pz8oP2E/P1RaD1U/LT8/VR0/Pz91Pz8kfBRrST95Mz8/2no/P10/Sj8vej8/Pz8mZT8/Uj8/ETY/M1M/VTg/PzFRVT8/PzM/P2xEPz8/Pz8nPw9RP0k/PyNuPz8sPz8/P11cbj8sP2o/Ww0/BD9Ubj9/Pz8/Cj8/UT8/RT9ydmE/VT8bOT9cPyYjMBE/Znw/SD9FGz8/Pz8/XT8/Ez9ePz8/Pz9iaD8rPzY/FncjEU4/Pz9+Pz8WOD8/PzU/RmRfeWdyUj8/ej9RP1E+Pz85Pyo/SyI8PyJhP0U/Ln4/Zj8ZPz8/Pz8/Phk/DD8/ZXNdK30/Ty1qPz9WPz8lPz98UWpZDlA/P3JbTT9xP10/PzUTPz8RP1g/ND90Hj8cPz9GEz8/LT8/KT8FPzQyYT83MRc5RwU/Pz89D1A/S15cZz8/DD9aPD8iFT9WIT9HP1M/P3FhPz9xfT9OfT8aPxk6Pz9URD8RH2tTP2JxPz5ZN2U/RENfPz9kTT8RP1w/Lz9GP0U/dUQ/PzcUP10/Pz9Waj82Pz8vPz9dEFs/P3A/Pz80CT8/MjU/OWtYPz98Pwo/Pz8/P1M/ZD9kZjw/TjJqRj9dUDU/Pz8/Pz9aPzE/Q3cTCT8lP0EvKAo/PzVRPzU/P1c+SxNfOxg/Jj8/AT8/P0xhGT8/bz8/YiQ/WD8/P1g/Pz8/awY/P10/f0lrPzY/DUA9Pz9CMz9eAEc/PlR+Rz8/PypkP1Q/Pz8/P0Z4Wk17Pz8/Pz8RPyM/PxU/P1kDP2I/ajY/Pz8ZXj8/Rzs/Pz8NP2dXPx0/P0ZVbD8/Pz8/bwY/P3gaP18/Oz8/JWs/BVs/dz8/eUU/P1JcYj9ZcT86Pz8/C2w/flpfekI/X0o/P2TWP1lTZT8/b3Y/Pz9TClYUPzEnP2NtI2w/Gjc/PxY/Pz8/RB8/PyM/Px1yWE0/NEt8PxY/Xz88P0c/NwxrVFM1Pz8FP14/Pz8/Ez93ET8/Cj8/P0xqVj9nP2l/Vj8vPz9vP1hOfT9pOxcIPz8/Wz8/Pz8/Pxk/C2knPz8QXD8/QXE/C1w/JD98Pmk/PxY/Pz8aPxluPz8nYT8/blxOfj9kbj8/Zj8UPxk/P0JyGhNoFhJ7Pz9DRT8uPz9jej8/az8/P1k/Pz8WNH4/Wz8/PyM/Mk0JP1wJP2E/DUQ/Qj8/GXFWPz8/JD8/cD8XPz8/bQNwUV54KiE/Pz8meg8/P0E/GD8/Pz8/TVQ/RT8zPw8/P3Q/G0NvQzpFPz8/aT9GOmVAOlAuP00SPz8JP1YCdj9yPyA/Pzc/amU/GwAPPzE2Pz8/P2RQdj8/GD8DQko/PEc/UkE/FT8yPz8lPz8/ED8/PwA/Tgo/FT8Pcz9dABZXciE/XT8/Pz8FPxJKST9kP155Pz8/ZT8MPz8/AD8gP0YsPz9UPXgBaD88PwMLKz8Efj97ByE/Pz8rFl0/P0o/Iz8/Pz8/bR5jMD8/LD8/PwU/P2Q/Pz88F0wHPz91ODYaPz8/B1E/Px1OCT8/Pz8/P0xzPH14PyY/cD8eICYgDhk/P2Q/Pz9NKgc/Pz9LPz8LCSo/Hlk/P1k/P31oP04/C0Q/ZT8LPz9TPz8/AmhfPy0/Qz87RD8aDRUaJT9GP2lWLD8/PD9wPz9hPz8/DwkrP3U/Rz8rPz8/Px8/Pj9/Pz8/P2o/az9oP2s/az9qP2o/Pz8/Nj8/fT8/Rj8TPz8/P0g/Vjo/PT8xbz9JPz8/fz8/Olg/NGM/ez8QPzRrPz8/Pz9xP14/ej8/Pz9CTgI/ND8/Nz8/ND8/P0k3Pz8CPyNJZz9VV1dXVD8/UT8/WT8/P115PxY/Rlw/ET8jLmU/DmU/RVhzFz8PZT8fISJePz8RPws/Pz9CRSFiP0QkCFM/IC8/UUY4P3xFBD9RQggccD8hJj8/BD8TP2s/PydZPz8ZPxBFHGxLWT94AAAAPwByCQAYPwFmIAo/BGBiYBAGCWIDP2BgZGBjP3gAPz8QPwc/ulgPPz8GDT82HCBAPz91LxAaN20/Pz8QP0hzaD8/egA/JXRbPz8uPx0RMT8/Pwg/PyIQPyJbP2A/FD9ySxU/Pz9xXj9UehQ/UiAqCD9BPz8/Pz8/Pz8/UlY/Pz9rez8/djksVCE/dDU/Pz8VFT8/P0VhTVI/Yz9fPz8hSWltPz8/Fj8SSnFhPxcZPz8RFShqXRc/P0k/EXkuPz8/VT8/PwgYOGJJPz8/P2JCPz8/Kz8/JVU/VT8/Iz8/VT8jKz8/Pz98PwI/Pz8/P1JrPyw/Pz8/PzdHPz8kLz83Pz0/P2k/Hj8/eT9uPz9eP1Q/Dj9KTEs/WD8/NT8/Nk4/E2Q/dyg/Nj9iPz9bPxQ/d2FYP3l0ND8/Rj8xPzc/Pz9fKD9zP3w/P2g/P1ZmYDx8Pz8HYz8/Pz9QPzMcSFN/PR8/Pz8nZz88Pz8/P0ITPz8/Hz8/FHFsP0U/KwsxPz8/aFg/BXM/MD8/P0c/TT8/Pz8SED8/P1YrPyU1P00/az8/NT95RWY/cT1pb1E/Pz9OP1k/V30/dj9yPz8SPz8/Sz8/Pz8/eVU/VT9UP28/VD9UPz9RP08/P2toSxs/SHY/Pxw/P08jRT9/Py8/PyovPz9iP349Pz8iPz8/WWc/Py5aPz4/PS4/Pz8/cT9TZj8/P3Y/eD9xcD8/RwcYTT8/OS4/Pz8/ED8/Pxk/Pyk8DRI/dD9lP0A/Sj8/P3xbPz8kPwdOHVg/ND95cj8/Pz8/dj8uP1M/Pz9+BzonLj8UP0tLPz9WP3w/Pwc/dzY/P3E/GD8nPz8NP04/P0M/AUU/P2s/P0s/Dz82SHJdP04/UUppKj8/BmMrP0g/dj9IPz80az8/F2hQPw5IPy0/Pwo/fD8/FRo/PyI/ZW1iPz9eGV05dGU/DStMPz8/J1w/Pz8/GT8/Pz8/fD9pP0M/NDk/JnRFPz9OQXo/WDg/BDM/P0R7eC52QT8/b1I/Pz9zP1JRXSluP3o/Wj9vPz8/Pz8/Pz98Pz9IGkM/PxtbPz9HEj8cNj9xc2IBXD9UPxc/PxY1P0VRP2kSUm8/dT9ZBD8/RlU/Pz8zPz8od2E/USc/VEQ/Pz82Pz8/Uz8/KVgUPz8/Px0/TnE/VT8/J20/P1BRMD9yP3g/fD9Uaj8APyI/EmU/Pj8HPz8/Pz8rFQ0/Ij8/Pz9oQX1kPz80P38EPxRcPj8/FD8/P0o4Pz8/Fz95P2U/eipSVj8/RWw/ID8/EAU/Pz82P1c/Pzg5PyY/WnA/Sg4/WwgcKWElHw4/Pzk/Kl4/Pz99P0I/IWE/P1E/TT8OPD9GPz8/IzIpPz8/Uj8/Rj8/bmo/LT9RUj8/WzVHAz97Mj9ycm1Uej8/cTY/Pz96Pz4/XTo/BT82XHg/Pz8/Pz91Pz8/VwobPykpFj8/dnI/bDo/EDJdP1M/P2g/UVc/PwBRE2w/Pz8TPz8PPwo/Pw82P1B/P1Q/P0sceQQ/fC1PPz9mPyA/Iy4/Pz8/YT8/JRtSPypdUXo/EiZaWlA/Pz9TPj8/P1s/PxNdP2xeOkVCXD8fayElPxVvP2w/NXE/Ok0UST8/LT8/MD8kPz8SP1Y/VT8/PxxlGj8/dj8yP0c8Hj8/P0c/ej92PVknHD89P2FIPxAxfk0/KxZhP3QEPz8/Fj8/P1k/FgIHPyY/P1FoPz9vHT9TQi9oPz8JCW4/Pz93PR4/CBU/dD87ej8/P3khVwo/RXQ/Py0oKD9adT8/Xj8rWD8/KT8uP09WPT8wPz8hPz9eP2Q8C28/PyE/P2R6ez8/Pz8/ID8/P206Pz8/fj9aP10tdD8/P2o/PwE/PwQmPy0/PT8/P2E/Pz9rEnY+C0A/P3dNUT8/Ez9xXj4/PxM/c1ZrLT85Pxg/Pz8/P3M/Pz86PxQ7Gj8OZB9RPyhzP3c/Pz8MBj9zVD8Xcj8/Pz8/Kjo/GWY9PxZ6PD8/Pz8/Pz8/Yz9FPz8/P0wfP2o/VT8qdhY/cT9WPz9WP3U/P1c/P1s/Pz8/P2M/P2g2Pzg/FhpXPAg/I0o/Cyg/EAc/P2xKPz9JKT8/MT82PxQ/PxZyPz8/Pz8/KU8GP15aTT8/P0YYdD8/cz8/Pw1LWioWP1c/Fz8/Qz8/P2JOQ2J8fD8DFz8/EDY/Cz8oYGc/DX8/Bj8LPzVzPz8gP00lSUFkPzoNPzBvHnkBP2glPz9mLz8eTz8nPz9ieD8hPz9PZz88PAk/agZ1HUA/Pyw/PyN8Zh9pMwcqPyM/Pz86P18vPyk/Pz80HD8uPx0/Pwo/P0k/Q2A/Jj8TPz8/PzYePzg/Zz8/Fl4/F2k/Pz9DQT9vP3QcP0Y/X3M/PxdyBQ0/Pz9LP0orZT8VDT8DPz8/LVo/bVMhPD94PxN0NT8/DT9dPzsOPz80PT94PwocP2Q/WUM/Oz8/P14kTAA/eG8/Pz8/PzM/Pz8/Pz9fP2drxl4/YT98TWFXP346aj8oPz92Pz8/Pz9XWT8/P1s/RA5gUz8/e1k/NjI/Pj8oP1ATMz8/P14/Vj8/csY9P1w/XQhjFwV0PzQQYE1LP3ZKcAs/Uz9KPz8/Pz85Pz8/NGc/cj9ZSEA/Qj9OVnU/P2g/P00zPz99Pz8uPyM/fT8KFj9YLj8/Pz8nPz9jPzhZP2Q/P197Pz9nQTo/P0clM2BTYG1gMj8/P3JxTT9ESj8sSz8/OCV7PxdXCj9NOz9AUH8BPwQ/Pz9kLT8/Yz9ePz8/Lz89Pz9pPxQ/Tz9RZT9zPz8/Pz8iPyA/ShxHET8/FT97Cy9nPz8caz9xGz8/aT8o+T82eScoDmQpPz8/bXY/XT8fPz8HPz86Pz8/PzI/azJDZDRgHQVoTD9KPwdoZD9lPzk/P2E/Pz8/Pyg/Fz8/Pz88Pz8/zT8/Dj92Yj8/LiFYOT8/PywzVD8uP0NoP0o/c19OURo/WD85P5ojRgw/Ij9tP1gIOSx4dj9gaVg/PxM/Pz9nYD8/PxY/YT9hPz8DSxtwbBQ/P0U/Pw8XenI/P24/PzkKPz8/DD8/Pz8wPxAHST8/Py8/P346SD8/PT8/P2Q8Pz9YKFgiP0I/Kmd/Pz9MPyA/Pz9vPyM/Pz8SFT8DPz8/CH0/CT9gP3IZeQQ/SFg/Pz83aD8/FT8bbT8/FT8APzEfPz9jP0c/Pz8/PyEwPz8xaH4/P3JnZz8kQ2o/c05EP2xzfj8/WXADPwoGTVsePz8/eD8zPz8/Kj8XBmVLPxI/OD8fTz8/Pz8faj8fMhA/P34/Pz8RP0U/flQ/V0ECPT8rPwwvbzo/Pz8/Ej8/Pz8/GzscIW8kPzl0UUItFEU/Pj8/Pz9JP2coPz8/aT9neho/Py8/P3U/Pz8hQz8/Dz8/ZT93Pz8/O2kFP2tBDGg/VWk/P2UsPz8/P10/ZitLP2w/P3Y/P2Q/P1Y/UhM/Vj9bP2w/P3lTVT8/RTZFakUaPz8/PxQ5FT8/P3gbP30fNj8/bT9oaj8TSk8/dz8tPzRiPz91Pz8/P1c/a2kzCz8/P3RrPz8/Pz9CPz9VPz8ob0U/P2tTP3t5eD8/Nz8/Pz9ZKT9vPz9xBnE/OV4/Pz8jGFMhTD9ILT83P30/Pyg3Ag5aP2g/GgxoKj8/Pz8/P1A/Pz9aPz8/XA4/Rj8mP34/az8/RHI/Sj95FShaIj9jPz9/P1s/Dj8VPz9/Pz8MPyM/Qz9WPz8JPz8/dHozP3k/Py0/Nj8/BWMNPz8APzhJPz8oVGQ/fVs/Pz8/Pzc/JFU/Vj85IQpiSho/CWw/X1UgFAZYQz8/Dnw/Qj8/fhE/Kj8gPz9YIz8/P1AIWGNBDT8/Uz9RPz8SUz90Pz9KKGc/Pz9Qbj9ASyQyEGE/alIZBRMUPxRLPyQ/Rg8qP2A/P2M4HT9SPwlHCkhhXTw/Pz8/Pwx0PyU/P3B7RD8HPxtAPz8/AT8VPxQEJwU/ET8/Pz9ecGdGZgQ/HT9jGR8/Yj8/Pz8/OUg/Iz+yJj9YdGAZPz94Rj9SP0I/JT95Pz8/Pz9HP0RDPz8/Hj8/XgN3PzgWP2w/Vj8/CT9PP20/P0k/P1o/P1U/ST8/GT8/Pwc/BT8/OD8/Yj9HPz8OPx4eP3s/VwdMP2xmP0pcP0U/WmIMY2Q/H15KCz9dP10LfmY/BF5KP0Q/LS5zPz9IPz8/NGY/Yn5IPz8/dD8/Qz8/Tz8KOgI/P352Pz8/Pzo/WSE/Pz89XD82P0o/Pz8/RTI/Pz8/Kh4/cD8/PyM/OD8/P318Dz8/Pz8/AwoPPz8/fz9kIRI/FHU/Pz89Nx12PzpiPz8qWUI/Pz9UGj8vChpZXxsoPyM/bD8SP28/Pz8zP2Y/Pz9cPz8IPz8/EjA/P3E/P0g/Pz9RFxRUP0E/CT92Pz9BPwY/Pw0/E1s8JT9PPz8HXgYePwI/Jz8rPz8/Pz9oHj9WP2I/Pyo+Px1iPwU/NhE/Yj8ZP3R1P3ILPz9dP3Q/Yz8/ZzY5fD8ePz8MTwNHP1U/Pz8/Pz8/PwY/Zig/P2BJPDE4fh8/cz8/P28/Pyg/P14/Pz97P0o/Pz8qJT9nYRs2PwU/KWI/dSgLPxgoPz9TY2MZPz8/BT8/DjxZPz8/EwxtP2A/SD8/Yz9DP0c/Vz8/PwIaP0pMJCUyPz9gP380Pz8/Gj9aP04/Pz8/Pz8ePx4/Vzg/PyUOPzoPPxNTP3VVPz8/WVo/Pz8/P09HTD8WPz8/P34/P1o/PwkEOTk/Pxc/Pz8/WD95P0A/QSQ/PyUEPz8/f34lexRoFT8/Jz8ERD8/Pz8zO25ePwJHQD8/Pws/Pj9dYzQ/PwIGQj89Pz9IPz9xPz87aA0/P1Y/R20OP18/Pw8/P29uPwk/Pz8/NiBOGz0/P38/Pz8/RD9PPz8/fz8/Dz8/BjVjPz9mPzRcXi4/P150aT8/P1Y/P3RoJT8/REcKPz8cPz8/Kn4/Pz9DP2hGP0xHfFYtP1k/Px1RPz9/Pw8/Pz83C08JaR0pFko/Pz8rQmI/PyBdNj8UOHA/Pz9KaGY/P2ltPww/CT8/KB0/FQk/dExvXj8/Pz81Pz8/ekpEbT8/Pz8HPz89QhdoJj8/ThM/Pxo/NT8lPz8nXz8/Pz8KP2hvUT8/bT8/Gz8/PzsPTzM1Pz9HPxNVPz8/Pz8sWmM/P2FAFT8RPz8/Pz8/P2l2UD80Pz8/Pxg/Dmc/XB4/P0QFPz9pPykaFT90Gj9DDhZyP1k/G1A/PwhlUz8/LkkqOR1vPz9vODQ/BD98Pz8AWD8/Ej8/PypoPwQZPz8/aQg/Nz9vVmA/bT8/P2k/Bz8/PD8/Pz8/Ig9oGj8/P0ErZms/WyQ/Pw0/Pz4SP8M/fXE/Bj8/PxZ+Px8/Yj8SVGU/PixiLwI/Ij80Cj9acj97Pz9+UD0/P2A/PxY3UwxkNj8/WzQ/Pz48UD84dCE/az8/dz8DPz9rDgEKPz8/Pw4pPz8hP3B1PRY/BmUJPz9UPz8ZMmA/P10GPz8/WD8/VxZjPz8/Pxw/P2I/P25YPx9yDj8CPzZsPz9iP2dXPz8/Xz9WOGgBP00/KxlKPzNDZl4/Pz8xTXovPz9lPz9hKT8/Uj8/Pz8iMRgNcX0/PyA/Vj8/PwE/BggQMHViPyQ/W18/Cx4/MD81Sj8sNhxZPz0/Pz9HPz8/Vio+Pz8yE0w/A0M/P15xPz8qdD8/fT8/Lj8/Xz85Pxg/ET8/NT84BV4/DWcccnw/Gj8/Lj9FWj8rCzQxfD8/PxsALj8/Pz8/PyQ/P24/Mz8/PzszASBJCQRLBHN6Pz9WP1k/OGI/Dj9fPz8/Pz8/Pwk/Pz8UPz9+Pz8/GEc/Pw59Tz9Yb1MQW14kPz8/P2k/PzA/Pz8/PyIxPz8/Pz8/d2ZePz8/P0o/Pw9nOz8/bD8/P1E/Nz8iQzA/P2Q9Pz9hPz8tPz8/LFM1KXE/Pxk/Pz9gPx8/Pz8/P0k/PxQ/NT9JPwg/BT8jUj9TPzc/Uz8KPz9XPz8SPz8/cloPPz8mF04/ZD8/GD9HP2VhPz8/bWwgPT9EZj8/WFEuGD8aPz8/Gj9KPwQ/P0g/Pz9yPz8/P0JMSAQ/ez83ID8/P2ptVA9LPyw1Jz8/Gz8/P30/Pz8PI3E/AT9qPysDP1A6Pz9MPz9IPz88GHs/Pzw/Yz8eP3gwPz9WPz9PPz8/HQslZQZ9P0x0P2e3Pz8/Pz8/Pz8/PzRTP28/Bz9JPz9WWWt7Pz8+K0c/Pwg/J3M/HEU/dz8/ez92Pz8TPz8/ACk/Pz8/Qn4BP0EDWD9hP0k/Pz80DRYHOHk/Pz8/Pww/ej8hPz99P1gfPz8/Aj8/Sz9eVCQcQhk1Lio/Pz9dDz9YPz87bD8/SD9ePz8/PyI/WSQ/P1o/P2lFKj9OPT8wPzw/DT97QVdfP1dCDT8/Pz8/Pz98Pz8/dz9IPz8/J3I/fSM/Pz9BPz8UKj8/P2c/ID8/Pz8/Pz8GPz8/TD9QPz8/Pz82bT9oGkk/fh44P1ATUVsCPz8uPz8/Pz9NA2gaPwI/Pz8/Py1nHj8/XSw/YTQ6az8/OD8/Pz8ZIE1nTA8YPz9LHQE/Pxg/P2JJPz9jSDphPzc/MT8kPyg/Py9GHDw/Pw8vP0U/Pz8/ET8MP1hgwT8/MQYvPz85Pz8LP38/Pz8fNj8/JSNeLAYnDT9GP20/SD9mP1syaSE/dj9WPz9XDT80CT8KP2I/Tz8AexNLDgQ/PxV8Pz8/Px9tdQQ/SDE/ez9vQz9AVj9wPz9OPz8/Gj8eRz8ePz8/HnE/Fj8fP3YOMD8/Pz8/PxQEPz8nNj9bPzogYF0KOFdWP1Ihbz8/PwkENj8+Mz8/DlM/P3U6f0IePz9iKj9OP20/RD8/Pz8/fj8/XT8/Yz8/cAw/P24/PzM/Wj8/Bz8/RB9gUj9CPx1qPz88Pz8/PD8/P38/Pz/rP2Q/ETs/Vj86WGc/Vz9JbD8/EjZiPyk/P14/Pz8/PRY/P0NaESA/Cj9hPzQcYj8dRXcvCz9hPVU2Yj8/az8/PyMIblNQP0g0Qj8KEjk/bz8/Pz9mPz8/aj8/MT8/VT9HeENoPz8bPxwoUxhoUmt3Oz9ybE0LQT8eP08/Pz82GD9zPzchPyA/PyUfPz8/NT8ffT8/bB8/Rj8/YT8/YD8/Pz8/GG0/P1A8ZT8/ES0/Pz8nUT8TP3EdAlhqPz8/fj8/PzdZUhU2PykmPz8/LGk/Rh0/MT0MP2c/P2E/Gj8PPz4/Pz9nP34VPww/Pz9ePwVgPxghPw4jPzE/Pz8/GD8YPz81UjM/aXoDS0YXP1oLQUNZYz8/D2J8P0BpMA4/Pz8RWBZITAc/P1A/Pz9AP2A/Pz92UT8SPwxLP1U/Pz8zPz94Py8/PxU/Dz8/Pz4PPz8/Pz8XPz8/Pz8BeD8YPz9/Pz8/Xg4/P2E/Lz9BInMUPz84LQc/P0xYPyY/Lj8/LBQ/Pzk/Pz9LPz9SPz8GPzFjAnk/PxlhXj9+TDArPwk/Pz8/RAoNPz8/AwtOPz8/Pz8/Yz8/Xz8/Bj8ePz8/Pw5dASBMaD8/CzMmPxk/Pz8YGD8/Dz8FPz9yUj95P2o/OT8/Rz9dPz8GPz8/WD8/Yz8/Pz8/Pz8YPz8/Gz8/UVQ/Pz8iB2Q/Gz9hPz89bBc/Pz8/SlkyPxsAYSsEUD8OP2s/PwZDPz8/HT8/fD8/P3Urag4/Tz8+PyQ/Pz8/bj9NPz92P1ZVP1I1Pz9TP2c/P1w/P0k/PzZqXFg/WWN+P144Pw9OPz8/Tj9DPzw/Pz8cP31SP2Jzbj95P04/Q2hKex0/Pz8ceFA/Xz8/HD9hZT9OMT8MKUF7aD8ZPz9DPzM/Pz9DQm0IaAQ/Py4iPz8uP0w/IxgPP0Y/P22ZPzk/Wmw/P2YAPz81HXo/Pz98Pz8/P08/KwJKfD8/P2gxPz8/Pz8iIz9qFj96CG0XPxFsPz8kPz8hHj8jIhA/Py4UPz8/TDk/SHszPz9TBFA/Iz8/P0kaP056Ly4/Pz8/Fj8jEQA/dT8/bRkMOT8/ZxU3P3w/PwY/dT9HFT9ePz9nP34/FCs/Pzc/P2k/JTA/Pz9Eej8/cT9oPz9KP05ePz9zP04/PwQ/CT8/NT8qPGJNP0o/Bls/P397Py8/Pz9zElhXQj95Pz8nPz8/P2ENP30/Xzc/Gj9PNz8/XD9+PxU/Aj8LPz8/Pz8/fz8/P3AOLT84X1M/Pz8raG9UP1gBSz8IP3FtPz9/Pz8/Uz86TR8/PT9zTFs/Jj8oPz9sPy0/cT8/Pyg/Pz8WPz8zPzl9OiVUenQyPywRPz9YPz97RCJQMT9JPxE/JD9VOBAKQHc/CjoYPy1tIT8/Ez9ePz8/B1B5fz8aDj8/bz9xPz8/Gj8SJQI/Onk/ZE8/Pz8/Pz88P31nPz80Pz8/P0c/MT8/QBI/PyoYPz0/Pz8OCj8/P0w/dj8WDT97MR8OPz8VNT99TD8/P18/Pz8/ET8/A3Y/Xj8/LT9BYxglP2Q/Hmw/WT8/Pws/Pxs/PzI/P2cuPxI/Pwc/Pz97AW0/KD4/P3A/WQV0Pz8oPz8/LSM/P1wFQVZAVj8rTj8wP3E/Pz8APzs/Pz8HPzU/Kz9pXT8/Hl0/dmo1P1I/Pz8/cRQ/Pz8/VD9WbRUDBSs/GVc/P3U/ZDE/Pz8JPz8fP14/Zyg8P0M/ZD8/Nj9tPyU/MD8RPzE/Pz8/Pz8ZP3QkP199P050P3E/Pz8/bwoTKD8/WHRVPz9WPzc/P1IqPxg/Pws/FD9IPw85PwxQJz8/fD8EPz8/PwFfPz8/Pz9rRD9VPxFnIVl5PyMUZz4/ED9FPz8qP2s/Pz8/OCxAPz8KPz9iOHo/Pz4ICiU/P3U/L3oLP2k/PyA/Bw5AFhQ/PxQ/PzM/XD8/Bj91fT82P0BFPz9RJC0QQ1Y/P1s/Zxp2P04/PyY/bVM/RT8/Pz8/UD9wPz8NPz9dDAdsPxFLAz9zPz8/P0dZNykCPz8/P0o/P3QsPz94B1wRDA8/Pz8/Pw42NPE/Q2E/Pj9xPz8/GFhDP0MPA30/Pz9OP21LP3M/Kz8TP0I/P0VEPz8ZPyoeTz9wJX8JP08/Xn1IMz8AQ3k/ZWIEQxY5Xj8/X0RxcX16Pz9LYz9SPj9FSD8VP0sPHWA/Pz9rfHM/P1o/aWMRPwdUP00/LAtsSj8/ajkIPz8WPzUTAz8LPwoeXlg/SXw/P3YJWnMfDz8/P1I/ED8CPz9FED8/ST9SZ3J2P1o/ZAozZj8/SD8OSj8/P3U/Pz8ZPzZqBj9oOT8/Hz9lP3Y/Oz8rUjQcPz8/Pj8/OT8PPyY/P0Q/PyM/DS9OSz8EYT8/FiYaWCBpPz9TAQ1LPz8vGEBsUD8/Gz9Fbj8/Dj9ZPyc/Fz8/MT8dDj87Bz8XKD9qRj9lPz9nNz8sKQo/Pz8/CkE/bz9BP3I/Pzw/P15GPz8PTj1KPz8/Clg/Pz9oP0sqalpYSlk/P1E/I34sPz8/eSQ/Fz8/Pxo/Fz88CT9+HWJRXj8/Pz8/Pz9MPz8/Pz85Pz9oP2k/Pz9cBT9mBD8/QX8/PzQ/XD9DDj8TRz9IXT8mE2E/ZQg/cHU/Pw8/Uz9xP1ZnET89P24/UQtrPz5xUy4/Sz8/aXonPyNAPzc/P1M/Pz8MZmc/Py94P28/Pz8/OT84GUl1Pz8/P1xOPzg/P3c/c2QSPxM/Pz8/Tk0VCWk/P15lSXI/Pz9ueD8/CT8/aD9VChFfMwNVVT9HP18/Pz8lWz9OVTRmPz8/Rj8/Sz9zP3otEkQ/P2oWP2ApPz8SZUtzP1RcP1c/Pyw5Pz9gPycnPz8/OT8/OT97Pz9hPwg/bic/Pz9+Gj8/P0k/Fj8DRT8kP24/Dz9PPj8vMAlSKz8YP00dPz8/DT8/Gz8/P0EvCHA/Pz8/T1Z8c0M/Pz9dPyNuOj88P39JPz8/LGgalz8/IxkPP1c/RT8/Pz9sPz9WSzF4DBs/P1Y/Oj9jPz80Pz8/P2hYPz9tDT9+P0daYT8/Pz9cOEo/cTQ/P2ZXP3Y+Pz8+P0M/WT8/Dj8/Qz8/aD8/P04/Pz82L1g/T1M/Jj8/Sj9iP1w/dBN0Pz8/PzAePz8/Xj8iRQoSLlAbP38/Px5pPwY/LT8waEY/P1c/Pz8bP0I/aD8QP2U/CUk/Zz9ZP0w/Pz5zP1g/P3UGCD8Mblc5eUo/Pz8/fFs/GH1BVRtEPy05RT8/DxRvLkNyAT8gfTw/KwchP0BhEj88GT9TYz99GhsoPz8/Pz4/cVc/P3g/Riw/Pz8JPz8/PzVoDVs/Vj9VP1VrPyc/Pz8/ST8/Tz8/TD8/PyZWPwNJez8/P28/Sz9QPz98PzM9PxY/az9aP1s/P3k/fT4XP3Q/fH8/Pz9/P38/Pi9TPz9/LD9PKdM/bx0/Pz8/Pz8afD9PPCc/Pz01bz8/Pz9tPz9YP2g/exs/Pz88Lz8/Pz8bY0Y/Pz8/X2hPPz9jPz82PT8/DSU/Pzo4Pz8lPyU/Bj8/P2o0Gj8/dkA/Ckg/NXJrPz8/P1s/DT8XN34yPx8/Fx8/Pz9bPz8/XX0/Uj8LP7g/P+4/Uz8/Pz8OcVU/P1dnFxhaP1A/HCpUP1Q/Pz9XP1I/VUo/P1dKP1M/KnlUPxVSP1o/SSpVS1Q/P1RtUj9aP1RUPz8/UT9TP2Y/WwNUPwY/eg1UP1Y/FUE/QRMSP2c/Pz8lPz9vNz9cLz93Pz8/P34/Pz9zLT8/P20uPz8/byMyPz4/UT8/dD9dPz9QdTI/Pz8/PwpLeUE/P1Ftez8/Pz8/Cz9ZSz8/fHg/PwJoPz9RPz8bUg4+P3NrP00/fz8bEz9mPz8LJz9ZOD8/Kj8/Py8/P3khPz8/Pz9TP1U7Pz8sP3VdVT8zPz83fT8/Pz8/SBJ6fz94ax05ARUFPxEEURRBQFwqLD9lBD8WQEU/Pz4/TD8/azJIQCYgP2EgPz8/EgRAPwEAP1NkVT8IEh4/Xj8/Pz9FMz8EPz8UeAl6P3gAPwE/LAAAPxg/GVs/PwBmYGM/eAA1PytvP10dP3U/Gz85Z2Y/Pz8/Hg4/Rz91MThdQT8BPz8/fz8/Hig/HT8/Az94Cz8bVgoZPz8dZj8/Pz8/MDowPz8/Pz96Pz8mP04cP2o/AT8/dns/dXZ1Pz9rbWw/Pz8/Pz8/Pz8/Pz8/P2w/Vj9vNj9cPyorPystLGw/cD8/Ki8/PygvP08tP2o5Ez8/Xj8/Pz9jXj9XPz9TKxU/P1l0P15OLRY/EhM/P1kVFxc/Ej9nMT9nNj80TD8/YD8/Mz8/Pyp8Pz8EdHI/e0MoRT9SP0c/OD89Pz8vNGI/Pw8/Pz8aIUIhPxQ/QBdQP2E/Pz9sPz8/Nz8/dj9NP11EPz8/IT8YPwM/Hj8LQT8xP3E/PzQjRD1uPj8vdyshSkc/Pz8LcBcOcWcaYUwJPzFaPVAtKT9YPzo/Zj8/MT8/Rh0ZPz8/KT8NeQ0/Pz9PeRk/Hyc5DS18P3A/PxVhND8+Vj8/Pz9BNANHP1o/P3ZGPz9JBj9PP3gYCz88Yz88fT9QPz9zPzA/cEE/JSo/Pzk/P3A/FUIoUyI/EXw/OUMlPz9KND9GPz8/P0o/KXI/KD9fAT9vEj8/BD8/BmI/Jj8/Cj8uIj9OID8/PwJBPyw/eD8/Rnw/PxY/Bj8EOD8LP34/VUl6P3s/PxdnP0Y/Yms/Hj8/MTE/P08TES4mNT8PGj8/P3g/ej8KCjsgPzI/Pwg/Ags/A0A/OCMDQzRbYj8/Cj8/bD8/PxhBFExJPz94ACZqPz9vPz8/Pz9vHz8PPz9EPz8/Pz93Pz99DQk/Pz8/Pz0/Pz8/Pz97P0k/XD8/P2l1VDw/Pz9jPz9LPz8/Pz0/Pz8/P25Of3ljXT8/exA/Pz8/cz8ZPz9+Pz8/TyUGPz8/P3FAPzs/Pzc/Pz8/TxUubnk/HCsUCnkuRyU/bj9TSj9yPz8/EiM/Tj94Pz8/Ej8/Wz8/Pz8NP1c/Pz8oP1o/P24/O1VVcFo/ITtTVns/E1U/Pz8/Mj95KD8/PBNXPw8/Sj8/Ow8/Pz8/PyhqPww/P3k/PxA/Pz95Hj8jP2Y/aEk/TT9SdxlXKz8/Pz8/P2I/PyM/P3M/Pz8/NQtWP1BzPzE/Pz8BUT8/Tz8/P0M/P18/YjkMPz8/cj8/Pzo/CmRDPzM/dgYuP04/KT8/Rz9bPxpiBT9ZTxdaPz9zPxU/Jz8iPxFGewY/AD8EP0I/P3pYP2M/Pz8BPww/P0BWPys/Pz1ABR4GRzE/P10/BFw/AGhxPx0OPwE/PzM/DT8/aEo/Qj8/ZT8WPxc/P3BPP0s/Pz8/Zj85P38GPz8/ZEU/Pz8/GT84Pz8/F0p3Xxd9Pz8/PyNFCj90AHw7Pz8/P30/Iz8/egksPz80JQw/PyM/Pz8/Pz8/Az8/NRc/EiIhPz9nSD8jPz9vbj9HPz9SZT9EP08/bWNlL2E/P0gRPys/F1w/XkM/QwRoPz89P0s/ZVU/Vz8/Jxg/P18/ez9mUGA/TD9UPz9APyBvUD8sRkMqP0o2OQlQPy5lSz8/Fj8pPz8/XD8/FAw/Py1CPy1bPz8jfmdpPz9EPz8/GR0/Py4/CT9SP2lZPzZlPxw/KxIiZD9hWSVvARo/GWg/ND8/Pz9tVT8/ST8CNT9kPz9FPyY/RW0yP14mPz86UT8/Pz8/HD9KP1BBPz8/XT9RBT8lEUk0Pz8/WD8/TD8/P1E/P2JnKkU/JD9MW2NRaD8hc0o/IyNYUhA/PxUiPz8/FTI/Pz8/P2M/Pz8/PxIpPz8/PzBPPz8/cT9+Pz8/ez8/MHBwPz9BPz8EHBNIPz9OUxYreD8/dk8/F04/Px5kbHo/Pz8/TT8/Pz8/HFdiMj8/Vj8Pfj8/b14/Ej0eHitjPz8zP0g/cT8aPz8/P20/Lj8tVj8/Pz8nP2A/Pz8/P3w/PzUbPz8/Pz91Pz8/Pxo/Pz9vWi0/P1Y/Pz95X1pvP3o/W3dCP3p/Pz8/cT9+bz8GPz9J+D81Pw01ez8/Zj8/dzlqPz8/fHg/P3Y/fHpsbj9cPxo/Pz8/Pz8/NT8/P1s/Pz8tP1k/VT8/OjM/Nx4/Gj8/Cj8/fQY/Wz9fPj8NTj9oPREQOzc/P2dnH2kIPwI/P0xVPz8pPz8PP3onPx4/Pz8ePz8IPy5YPyI/RD9FcT8/Yz9zPwNRUz8/KD8/Sj9GBj9gUUx9Pzg/P3JZHRBGP29NVD94ACAQXz8ACT8/FBh7TH8/OSA/PwA+GAc/Ez8Lfz8/ED9KQD9qHj8/eDAwBz8wMBYEPz9iMGU/M0IHPz8/Pz8/tD8/Pz8/YmBjP3gAAHkAAFAAAD8GPz8AEj8oIj8ZP1gvPz8/Pz8/Xz8+YGBkYGM/eFoKPzMACiQJPz8/ICVmYRYLfz8/Pxg5Jh0FPwg/Cz83Ays/Pz8hPBlpPHBkYGBgZGBjP3gyAD8/IAAAABMAAAA/CAAAdHNvcAQzNSg/CwAAPwQAAD8BAABlbWFuAFB5AAYAAAAGAAAAPwEAAHB4YW0bHz8JPwEAAHMBAABAMwAAeHRtaD8DPwckAAAAIAAAAGQBAABhZWhoP0dyAzYAAAA0AAAAMAEAAGRhZWgLAAAACAAAAAgAAAA4MwAAcHNhZ05aP2g/AwAAVwIAAGQGAABwYW1jPyQ/VWAAAABPAAAAPwEAADIvU09eLT8/PwAAAFoAAAA/MgAAQlVTRz8/aD9aHQAAPwcAACwrAABTT1BHBAA/ACAAAAAdAAAADCsAAEZFREdxUj8sAAA7IgAAPwgAACBGRkMAAAAAAAAAAD8GAAAmAgAAPzQAAAAAAQA8XgAAAAANAD82AABPVFRPRkZPdw==)); font-weight:300; font-style:normal; } \ No newline at end of file diff --git a/docs/static/fonts/332720/47EF802870551C878.css b/docs/static/fonts/332720/47EF802870551C878.css deleted file mode 100644 index e012278e87..0000000000 --- a/docs/static/fonts/332720/47EF802870551C878.css +++ /dev/null @@ -1,19 +0,0 @@ - -/* - Copyright (C) 2011-2015 Hoefler & Co. - This software is the property of Hoefler & Co. (H&Co). - Your right to access and use this software is subject to the - applicable License Agreement, or Terms of Service, that exists - between you and H&Co. If no such agreement exists, you may not - access or use this software for any purpose. - This software may only be hosted at the locations specified in - the applicable License Agreement or Terms of Service, and only - for the purposes expressly set forth therein. You may not copy, - modify, convert, create derivative works from or distribute this - software in any way, or make it accessible to any third party, - without first obtaining the written permission of H&Co. - For more information, please visit us at http://typography.com. - 171247-88474-20150623 -*/ - -@font-face{ font-family: "Gotham Rounded A"; src: url(data:application/x-font-woff;base64,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)); font-weight:300; font-style:normal; } \ No newline at end of file diff --git a/docs/static/fonts/332720/52BE923A462D3F7AA.css b/docs/static/fonts/332720/52BE923A462D3F7AA.css deleted file mode 100644 index 93e7cb801c..0000000000 --- a/docs/static/fonts/332720/52BE923A462D3F7AA.css +++ /dev/null @@ -1,19 +0,0 @@ - -/* - Copyright (C) 2011-2015 Hoefler & Co. - This software is the property of Hoefler & Co. (H&Co). - Your right to access and use this software is subject to the - applicable License Agreement, or Terms of Service, that exists - between you and H&Co. If no such agreement exists, you may not - access or use this software for any purpose. - This software may only be hosted at the locations specified in - the applicable License Agreement or Terms of Service, and only - for the purposes expressly set forth therein. You may not copy, - modify, convert, create derivative works from or distribute this - software in any way, or make it accessible to any third party, - without first obtaining the written permission of H&Co. - For more information, please visit us at http://typography.com. - 171247-88474-20150623 -*/ - -@font-face{ font-family: "Gotham Rounded A"; src: url(data:font/opentype;base64,MgA/Al0APwA9ACoCOgBdA1MAZQIzAD8BXQA/AToAPwI8AD8CSQA/AmgAFgNvABIBaAA/AmgAPwI1AD8DQgA/AjcAdgJAAD8CPABdAjcAYgIsAE4CHgBPAUEAPwI9AHgCXQA/AAAALAEAAD8BCgA/PwEAAQAAAAIAAAAEAAEAGgABAAEAAgAAAAAAGAAAAA4AAAABAAALHz8/P35/Pz9/fz8/Pz8/Pz8LHz8/P38/Pz8/Pz8/Pz8/Pz8LHj8/Pz8GfR8/Pz8/Cx8/Pz8/CD8/Pz8/PwY/CD8/Pz8/Px8/Pz9/fz8/Pwg/fT8/Pz9YRjQnAQEEABM/FT8/FBY/Dh8/Pz8/Pz8/Pz8/Pz8/Pz8/FT9YPwc/Yj8/bj8/P3V7Pz8Gbj8/Pz8/Pz8/eT8/Pz8/FWhzPwohFT8/CiAVPz8/CH54P30/Pz90Pz8/P3w/fD97PxU/PwU/CD8/Pz8/Pz8/Pz8/Px4/Pz8/Pz8/PxU/Fz8HfT8fPz8/Pz8/Pz8ePz8/Pz8/Pz8VPxs/CD8/Pz8/Pz8/Pz8/Pz8/Pz8/Px8/Pz8/FXBoBj8/CD8/Pz8/Pz8/Pz8/Pz8/Pz8/PwU/Pwg/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8ePz8/Pz8/Pz8IPz8/Pz8/Pz8/Pz8/Pz8/Pz8/Bz8/FVt3Pwc/cj8/ej8IPz8/Pz8/Hj8/Pz8HPz8/Pz8/eR4/Pz8/Pz8/PwY/Pz8/FXw/ZT8IPz8/Pz8/P3I/ej93P3Z/f3o/BT8/CD8/Pz8/Pz8/Pz9pPz8/Pz8/Pz9jP1Y/YT9sbnlWdT95P24/HmBhYUhNP2o/CD8/Pz8/Pz9wP3c/P3N7fXg/ch9vP3U/Pz8/Pwg/Pz8/fD8VSj8iPwc/fj8/Px8/Pz8/CD8/Pz8/PwU/Pwg/Pz8/Pz8ePz8/Pwd3Pz8/PxUqPwg/P3Q/bD98P30/Pz8/eT9vP28/Pz8/Pz8VFz9iBj8IPz8/Pz8/Pz8/Pz8/Pz8/P3s/Pz8/Pz8/Pz8/Pz8/BT8/Bj8/Pwg/Pz8/Pz8/Pz8/Pz8/Pz9zPz8/Pz8/Pz8/Pz8/Pz8FPz8/PxU/Px56fz97ej9/Pwg/Pz8/Pz91P30/dD8VPz8tPwg/Pz8/Pz8/Pz8/Pz8/P3Q/Pz8FPz8/Pz9yPz8/Pz8/dz8/Pz8/P3o/Pz8/Pz8IPz8/Pz8/Hz8/Pz8/Pz8/FVk/Bz8/eT8IPz8/Pz8/Hz8/Pz8/Pz8/CD8/Pz8/PwU/Pz8/FT97Bz9yPz95Pwg/Pz8/Pz8ePz8/Pz8/Pz8/Pz8/Bz8IPz8/Pz8/Bj8/Pz8VPwc/cj8/Pz8ffj8/Pwg/Pz8/Pz8FPz8GPz8/Pz8/cj8/Pz8/FTsrHz8/Pz8/Pz8/Pz8/Pz8/Pz8VPxI/Hz8/P3p5f359CD8/Pz8/PwU/PwY/Pz8Ifz8/Pz8/Hz8/Pz8/Pz8/CD8/Pz8/PwY/CD8/Pz8/PxVRPyY/Bj8/Pz8VQT9VPwojFT8GP2I/P1g/Pwg/Pz8/Pz8GPz8/CD8/Pz8/PwY/Pz8IPz8/Pz8/Bj8/Pz8/FT85PwojBD8KIhU/PwojBD8KIhVBPwoiFT9QCiEVPz8KIBU/Pw4ePz8/Pz99P3gHcB54fX14eD99Pwc/FQI/Px8/Pz8/Bj8ePz8/fQV3P3sePz8/Pz8/Pz8VPz8hPz8OHj8/Pz8HPwg/Pz8/Pz8FPD8/Pz8fPz8/f38/P38GEz8efz8/Pwc/CD8/Pz8/PwU8Pz8/H38/Pz8/Pz8/BiE/Fj9aDgg/Pz8/fT8FXz87Pwg/Pz8/Pz9+Pz9/P30/fT8/Pz8FQz8oP0U/KD8IPz8/Pz9+Bj8IP30/Pz8/BUU/KD9FPyk/CD8/Pz8/fT99Pz8/Pz8/Pz8/PwVfPzs/CD8/Pz8/PwY/CD8/Pz98PwU1PyU/NT8mPwg/Pz8/Pz8GPxU/Pz8/Pw4ePz8/Pz8/P3wHQQg/Pz8/HhU/Mz8OPwc/Px58Pz99fT8/Pwc/Px4/P1AkJz8+IQc/Px58Pz99fT8/PxV9Pz8/Pw4IP3A/ZD8/Pz8/Pz9+Pz8/P34/Pz8/Pz8/Vj9TP04eRmVVUAc/CE8/dT93P3M/cj8wPwc/HzlQRigIP1Q/Tj9aPz8/Pz8/Pz8/Pz8/Pz8/Pz8/cT97Pz8/Hj8/Pz8HPwg/Pz9GP0I/OT81Pz8HPx8/Pz8/FT8/PyEOHn0/P319Pz8/BxA/CChfVTI/Qz98Pz8/Pz8/Pz8/Pz8APz84Pz8HUD8ePz8/Pz8/P3wVP18/Dh4NPyg0DD8HPx4PPyk/Cj8NPz8MPwc/Hw8/Lwo/FT8/His/Dj8CPyM/Bz8eIz8QPwM/LD8rPw4/Aj8jPwc/HyM/ED8DPyw/FX8/Pz8OHgM/Px0/Bz8eGj8uICEyJRY/Bz8fFz8zPz8VWj8/Px4/Pz8/Pz8/fAcuCD8/Pz8eDz8oET86Pwc/Hzo/JhE/Dz8IPyU/ST9hBz8/Hnw/P319Pz8/FVk/Pw4IPz8/Pz8/BT8/Pz8/Pz8IPz8/Pz8/fz9/fz9+Pz8/Pz8/BT8/fD8/P3k/CD8/Pz8/Pz9+Pz8/Pz8/Pz8/PwU/Pz8/Pz8/CD8/Pz8/Pz8/Pz8/Pz8/Pz8/PwU/Pz8/Pz8/CD8/Pz8/Px4/Pz9+FT8LPw4ffX9/fQY/CD8/Pz8/PwU/P2w/Pz8efT8/fX0/Pz8HKD8fPz8/PwY/CD8/Pz8/PwU/P3U/Pz8ePz8/Pz8/P30VP08/Dh59f399fT9/PwckPx4/Pz8/P38/fRU/Az8/Dh59f399fT9/Pwc/P1Q/Px59f399fT9/PwckPx4/Pz8/P38/fQc/P1Q/Px4/Pz8/P38/fRU/MT8OHj9/P30HHD8ffX9/fQZYPx9+Pz8/Pz8/PwY+Pz8/ET8ffj8/Pz8/Pz8GET8/P0M/H34/Pz8/Pz8/Bl0/FhY/Dh8tLDUpPE8/Pz8/PwQ/P1Q9FT8/Vh8/P1k/Uj8/Pz8/Wz9VPz8/Pz9NP1M/Zz8/Pz8/CD9nP1I/Pz8/Pz8fP0M/ISM/IQ0/BD8IPzo/Xj90BVA/CHw/Pz8/fj97Pz8/PwVWPz8IPz8/Pz8/Hz8/alJFTUElP0s/ST9AP3o/ez9LP0E/cz90P0g/Pz8/Pwg/KXVEYUE/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8VNj8/Pw0/Dh4LPzE/Mwc/Hig8Pwg/Bz8/Pwc/Hz8/PAM/FT8/Pwg/aT9gPwg/Pz8/Pz99P38/P30/Pz8/Pz8/VT9WP08/IT8rPyhmPz8/Pz8CPx4hPy0/DD8HPx8VPyEnJj8IP0A/Tj9hP1U/aSA/Pwc/H3A/Mj8OPzc/FX8/Pw4eFT9GPjwHPx40TD8GPwY/Pz8HPx8/Pz4VPwQ/Px4oUTg1Bz8ePFI/Pz8/Pz8HPx8/PzgoBBs/Hic/OgU/CD8HPwg5P01IbjNvP1c/OD8HPx4BP0EHPw0/DT8HPwE/Bz8IPz8/Pz8zP0g/Pwc/Hwg/BT8nPxU/Pz8OHgU/OUEoBz8eK0M/Az8HPz8/Bz8fPz82BT8VPz8IP28/YT9RP0U/JT8/Bz8fZz88PwM/Qj8IP0E/Uj9TCD8/Pz8/Pz8/Pz8/Pz8/Pz8/P2I/dT8/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GAEWARQBEgEPAT8APwA/AD8APwB6AHcAdQBzAG8AZABYAE4ASQBFAEAAOQA2ADMAJAAhADgABQBAAHgAAAAYAgQAHAAAAAEAAwA0AgAAAAABABwAAAADAAAAAwAAAABlAHIAYQB3AHQAZgBvAHMALQB0AG4AbwBmAGIAZQB3AC8AbQBvAGMALgB5AGgAcABhAHIAZwBvAHAAeQB0AC4AdwB3AHcALwAvADoAcAB0AHQAaABtAG8AYwAuAHkAaABwAGEAcgBnAG8AcAB5AHQALgB3AHcAdwA5ADEAMgAwADQAMQAtADMAMgA0ADIALQAzADIANgAwADUAMQAwADIALQA0ADcANAA4ADgALQA3ADQAMgAxADcAMQAgAG0AbwBjAC4AeQBoAHAAYQByAGcAbwBwAHkAdAAuAHcAdwB3ACAAdABhACAALgBvAEMAIAAmACAAcgBlAGwAZgBlAG8ASAAgAHQAYwBhAHQAbgBvAGMAIAByAG8AIAAsAGUAcgBhAHcAdABmAG8AcwAtAHQAbgBvAGYAYgBlAHcALwBtAG8AYwAuAHkAaABwAGEAcgBnAG8AcAB5AHQALgB3AHcAdwAvAC8AOgBwAHQAdABoACAAdABpAHMAaQB2ACAAZQBzAGEAZQBsAHAAIAAsAG4AbwBpAHQAYQBtAHIAbwBmAG4AaQAgAGUAcgBvAG0AIAByAG8ARgAgAC4AZQBzAG8AcAByAHUAcAAgAHkAbgBhACAAcgBvAGYAIABlAHIAYQB3AHQAZgBvAHMAIABzAGkAaAB0ACAAZQBzAHUAIAB0AG8AbgAgAHkAYQBtACAAdQBvAHkAIAAsAHMAdABzAGkAeABlACAAdABuAGUAbQBlAGUAcgBnAGEAIABoAGMAdQBzACAAbwBuACAAZgBJACAALgBvAEMAIAAmACAAcgBlAGwAZgBlAG8ASAAgAGQAbgBhACAAdQBvAHkAIABuAGUAZQB3AHQAZQBiACAAcwB0AHMAaQB4AGUAIAB0AGEAaAB0ACAAdABuAGUAbQBlAGUAcgBnAGEAIABlAGMAaQB2AHIAZQBTACAAZgBvACAAcwBtAHIAZQBUACAAZQBoAHQAIABvAHQAIAB0AGMAZQBqAGIAdQBzACAAcwBpACAAZQByAGEAdwB0AGYAbwBzACAAcwBpAGgAdAAgAGUAcwB1ACAAbwB0ACAAdABoAGcAaQByACAAcgB1AG8AWQAgAC4AbgBvAGkAdABhAGMAbwBsACAAeQBuAGEAIABtAG8AcgBmACAAdABpACAAdABzAG8AaAAgAHIAbwAgACwAcgBlAHQAdQBwAG0AbwBjACAAeQBuAGEAIABuAG8AcAB1ACAAdABpACAAbABsAGEAdABzAG4AaQAgAHIAbwAgACwAZQByAGEAdwB0AGYAbwBzACAAcwBpAGgAdAAgAGQAYQBvAGwAbgB3AG8AZAAgAHIAbwAgACwAZQB0AHUAYgBpAHIAdABzAGkAZAAgACwAeQBmAGkAZABvAG0AIAAsAHkAcABvAGMAIAB0AG8AbgAgAHkAYQBtACAAdQBvAFkAIAAuAG8AQwAgACYAIAByAGUAbABmAGUAbwBIACAAZgBvACAAeQB0AHIAZQBwAG8AcgBwACAAZQBoAHQAIABzAGkAIABlAHIAYQB3AHQAZgBvAHMAIABzAGkAaABUAC4AbwBDACAAJgAgAHIAZQBsAGYAZQBvAEgALgBzAG4AbwBpAHQAYwBpAGQAcwBpAHIAdQBqACAAbgBpAGEAdAByAGUAYwAgAG4AaQAgAGQAZQByAGUAdABzAGkAZwBlAHIAIABlAGIAIAB5AGEAbQAgAGgAYwBpAGgAdwAgACwALgBvAEMAIAAmACAAcgBlAGwAZgBlAG8ASAAgAGYAbwAgAGsAcgBhAG0AZQBkAGEAcgB0ACAAYQAgAHMAaQAgAGQAZQBkAG4AdQBvAFIAIABtAGEAaAB0AG8ARwB0AG4AbwBGADEAMAAyAC4AMQAgAG4AbwBpAHMAcgBlAFYAOQAxADIAMAA0ADEALQAzADIANAAyAC0AMwAyADYAMAA1ADEAMAAyAC0ANAA3ADQAOAA4AC0ANwA0ADIAMQA3ADEAcgBhAGwAdQBnAGUAUgBtAG8AYwAuAHkAaABwAGEAcgBnAG8AcAB5AHQAIAB8ACAAbwBDACYASAAgACkAQwAoACAAdABoAGcAaQByAHkAcABvAEMAbQBvAGMALgB5AGgAcABhAHIAZwBvAHAAeQB0AC4AdwB3AHcALwAvADoAcAB0AHQAaAAgAC4AbwBDACAAJgAgAHIAZQBsAGYAZQBvAEgAIAA3ADAAMAAyACAALAA2ADAAMAAyACAAKQBDACgAIAB0AGgAZwBpAHIAeQBwAG8AQwBlcmF3dGZvcy10bm9mYmV3L21vYy55aHBhcmdvcHl0Lnd3dy8vOnB0dGhtb2MueWhwYXJnb3B5dC53d3c5MTIwNDEtMzI0Mi0zMjYwNTEwMi00NzQ4OC03NDIxNzEgbW9jLnlocGFyZ29weXQud3d3IHRhIC5vQyAmIHJlbGZlb0ggdGNhdG5vYyBybyAsZXJhd3Rmb3MtdG5vZmJldy9tb2MueWhwYXJnb3B5dC53d3cvLzpwdHRoIHRpc2l2IGVzYWVscCAsbm9pdGFtcm9mbmkgZXJvbSByb0YgLmVzb3BydXAgeW5hIHJvZiBlcmF3dGZvcyBzaWh0IGVzdSB0b24geWFtIHVveSAsc3RzaXhlIHRuZW1lZXJnYSBoY3VzIG9uIGZJIC5vQyAmIHJlbGZlb0ggZG5hIHVveSBuZWV3dGViIHN0c2l4ZSB0YWh0IHRuZW1lZXJnYSBlY2l2cmVTIGZvIHNtcmVUIGVodCBvdCB0Y2VqYnVzIHNpIGVyYXd0Zm9zIHNpaHQgZXN1IG90IHRoZ2lyIHJ1b1kgLm5vaXRhY29sIHluYSBtb3JmIHRpIHRzb2ggcm8gLHJldHVwbW9jIHluYSBub3B1IHRpIGxsYXRzbmkgcm8gLGVyYXd0Zm9zIHNpaHQgZGFvbG53b2Qgcm8gLGV0dWJpcnRzaWQgLHlmaWRvbSAseXBvYyB0b24geWFtIHVvWSAub0MgJiByZWxmZW9IIGZvIHl0cmVwb3JwIGVodCBzaSBlcmF3dGZvcyBzaWhULm9DICYgcmVsZmVvSC5zbm9pdGNpZHNpcnVqIG5pYXRyZWMgbmkgZGVyZXRzaWdlciBlYiB5YW0gaGNpaHcgLC5vQyAmIHJlbGZlb0ggZm8ga3JhbWVkYXJ0IGEgc2kgZGVkbnVvUiBtYWh0b0d0bm9GMTAyLjEgbm9pc3JlVjkxMjA0MS0zMjQyLTMyNjA1MTAyLTQ3NDg4LTc0MjE3MXJhbHVnZVJtb2MueWhwYXJnb3B5dCB8IG9DJkggKUMoIHRoZ2lyeXBvQ21vYy55aHBhcmdvcHl0Lnd3dy8vOnB0dGggLm9DICYgcmVsZmVvSCA3MDAyICw2MDAyIClDKCB0aGdpcnlwb0M/A0YAEgAJBAEAAwA/A0YAEQAJBAEAAwA/A0YAEAAJBAEAAwA/CVQADgAJBAEAAwBrBSIEDQAJBAEAAwA/CSQADAAJBAEAAwA/CSQACwAJBAEAAwBrBSIECgAJBAEAAwBRBRoACQAJBAEAAwBRBRoACAAJBAEAAwA/BD8ABwAJBAEAAwA/BAgABgAJBAEAAwBtBBoABQAJBAEAAwA/A0YABAAJBAEAAwArBEIAAwAJBAEAAwAdBA4AAgAJBAEAAwA/A0YAAQAJBAEAAwBXAz8AAAAJBAEAAwBAACMAEgAAAAAAAQBAACMAEQAAAAAAAQBAACMAEAAAAAAAAQAtAyoADgAAAAAAAQAKARECDQAAAAAAAQAbAxIADAAAAAAAAQAbAxIACwAAAAAAAQAKARECCgAAAAAAAQA/AA0ACQAAAAAAAQA/AA0ACAAAAAAAAQA/AGEABwAAAAAAAQA/AAQABgAAAAAAAQA/AA0ABQAAAAAAAQBAACMABAAAAAAAAQBqACEAAwAAAAAAAQBjAAcAAgAAAAAAAQBAACMAAQAAAAAAAQAAAEAAAAAAAAAAAQA/ASQAAAABACAAIAA/Aj8BAAAAAAsAAAA/AD8DPwA4PyADEj8kAAAAb0MmSAAAAAAAAAAASgAAUH8AAD8AAAAAAAAAAAAAAAA/ADIAPwEAAD8CPwI/AAAAPwI/AgQABQAsAU0CAgAAABsAAFAAABsAAAAAAAAAAAAAAAAAAAABAD8DAAAAAD8DAAAQPz8DAAABAAAAAAAAAAIACAAAACADPwM4PwAAHwIsPwAAAAAfAiw/AAAAAD8DCwA/PA9fPz8/LkEAAQAAAAEAIAAAAHgQAAAyAD8/dHNvcD8LAAA/AQAABDM1KGVtYW4GAAAAGAEAAABQGwBweGFtbAAAADAfAAA/Bj89eHRtaCQAAAA/AAAAAANhB2FlaGg2AAAAPwAAAD9HFgNkYWVoCAAAACgfAAALAAAAcHNhZzoDAAA8DQAAAj8/cGFtY2AAAAAgAQAASyU/VTIvU08gAAAACB8AAAQASABGRURHbw4AAD8QAABjPz9PIEZGQzAAAwA/AAsAT1RUTw==))); font-weight:300; font-style:normal; } @font-face{ font-family: "Gotham Rounded B"; src: url(data:font/opentype;base64,T1RUTwALAIAAAwAwQ0ZGIE+2i2MAABCYAAAOb0dERUYASAAEAAAfCAAAACBPUy8yVcclSwAAASAAAABgY21hcO62ywIAAA08AAADOmdhc3AAAAALAAAfKAAAAAhoZWFkAxZHvAAAALwAAAA2aGhlYQdhAwAAAAD0AAAAJGhtdHg9xwbVAAAfMAAAAGxtYXhwABtQAAAAARgAAAAGbmFtZSg1MwQAAAGAAAALu3Bvc3T/uAAyAAAQeAAAACAAAQAAAAEAQS6s5cVfDzz1AAsD6AAAAADQLAIfAAAAANAsAh8AAP84A58DIAAAAAgAAgAAAAAAAAABAAADwP8QAAAD1AAAAAADnwABAAAAAAAAAAAAAAAAAAAAGwAAUAAAGwAAAAICTQEsAAUABAK8AooAAACMArwCigAAAd0AMgD6AAAAAAAAAAAAAAAAoAAAf1AAAEoAAAAAAAAAAEgmQ28AAAAk4BIDIP84AMgDwADwAAAACwAAAAAB/gK8ACAAIAABAAAAJAG2AAEAAAAAAAAAQAAAAAEAAAAAAAEAIwBAAAEAAAAAAAIABwBjAAEAAAAAAAMAIQBqAAEAAAAAAAQAIwBAAAEAAAAAAAUADQCLAAEAAAAAAAYABACYAAEAAAAAAAcAYQCcAAEAAAAAAAgADQD9AAEAAAAAAAkADQD9AAEAAAAAAAoCEQEKAAEAAAAAAAsAEgMbAAEAAAAAAAwAEgMbAAEAAAAAAA0CEQEKAAEAAAAAAA4AKgMtAAEAAAAAABAAIwBAAAEAAAAAABEAIwBAAAEAAAAAABIAIwBAAAMAAQQJAAAAgANXAAMAAQQJAAEARgPXAAMAAQQJAAIADgQdAAMAAQQJAAMAQgQrAAMAAQQJAAQARgPXAAMAAQQJAAUAGgRtAAMAAQQJAAYACASHAAMAAQQJAAcAwgSPAAMAAQQJAAgAGgVRAAMAAQQJAAkAGgVRAAMAAQQJAAoEIgVrAAMAAQQJAAsAJAmNAAMAAQQJAAwAJAmNAAMAAQQJAA0EIgVrAAMAAQQJAA4AVAmxAAMAAQQJABAARgPXAAMAAQQJABEARgPXAAMAAQQJABIARgPXQ29weXJpZ2h0IChDKSAyMDA2LCAyMDA3IEhvZWZsZXIgJiBDby4gaHR0cDovL3d3dy50eXBvZ3JhcGh5LmNvbUNvcHlyaWdodCAoQykgSCZDbyB8IHR5cG9ncmFwaHkuY29tUmVndWxhcjE3MTI0Ny04ODQ3NC0yMDE1MDYyMy0yNDIzLTE0MDIxOVZlcnNpb24gMS4yMDFGb250R290aGFtIFJvdW5kZWQgaXMgYSB0cmFkZW1hcmsgb2YgSG9lZmxlciAmIENvLiwgd2hpY2ggbWF5IGJlIHJlZ2lzdGVyZWQgaW4gY2VydGFpbiBqdXJpc2RpY3Rpb25zLkhvZWZsZXIgJiBDby5UaGlzIHNvZnR3YXJlIGlzIHRoZSBwcm9wZXJ0eSBvZiBIb2VmbGVyICYgQ28uIFlvdSBtYXkgbm90IGNvcHksIG1vZGlmeSwgZGlzdHJpYnV0ZSwgb3IgZG93bmxvYWQgdGhpcyBzb2Z0d2FyZSwgb3IgaW5zdGFsbCBpdCB1cG9uIGFueSBjb21wdXRlciwgb3IgaG9zdCBpdCBmcm9tIGFueSBsb2NhdGlvbi4gWW91ciByaWdodCB0byB1c2UgdGhpcyBzb2Z0d2FyZSBpcyBzdWJqZWN0IHRvIHRoZSBUZXJtcyBvZiBTZXJ2aWNlIGFncmVlbWVudCB0aGF0IGV4aXN0cyBiZXR3ZWVuIHlvdSBhbmQgSG9lZmxlciAmIENvLiBJZiBubyBzdWNoIGFncmVlbWVudCBleGlzdHMsIHlvdSBtYXkgbm90IHVzZSB0aGlzIHNvZnR3YXJlIGZvciBhbnkgcHVycG9zZS4gRm9yIG1vcmUgaW5mb3JtYXRpb24sIHBsZWFzZSB2aXNpdCBodHRwOi8vd3d3LnR5cG9ncmFwaHkuY29tL3dlYmZvbnQtc29mdHdhcmUsIG9yIGNvbnRhY3QgSG9lZmxlciAmIENvLiBhdCB3d3cudHlwb2dyYXBoeS5jb20gMTcxMjQ3LTg4NDc0LTIwMTUwNjIzLTI0MjMtMTQwMjE5d3d3LnR5cG9ncmFwaHkuY29taHR0cDovL3d3dy50eXBvZ3JhcGh5LmNvbS93ZWJmb250LXNvZnR3YXJlAEMAbwBwAHkAcgBpAGcAaAB0ACAAKABDACkAIAAyADAAMAA2ACwAIAAyADAAMAA3ACAASABvAGUAZgBsAGUAcgAgACYAIABDAG8ALgAgAGgAdAB0AHAAOgAvAC8AdwB3AHcALgB0AHkAcABvAGcAcgBhAHAAaAB5AC4AYwBvAG0AQwBvAHAAeQByAGkAZwBoAHQAIAAoAEMAKQAgAEgAJgBDAG8AIAB8ACAAdAB5AHAAbwBnAHIAYQBwAGgAeQAuAGMAbwBtAFIAZQBnAHUAbABhAHIAMQA3ADEAMgA0ADcALQA4ADgANAA3ADQALQAyADAAMQA1ADAANgAyADMALQAyADQAMgAzAC0AMQA0ADAAMgAxADkAVgBlAHIAcwBpAG8AbgAgADEALgAyADAAMQBGAG8AbgB0AEcAbwB0AGgAYQBtACAAUgBvAHUAbgBkAGUAZAAgAGkAcwAgAGEAIAB0AHIAYQBkAGUAbQBhAHIAawAgAG8AZgAgAEgAbwBlAGYAbABlAHIAIAAmACAAQwBvAC4ALAAgAHcAaABpAGMAaAAgAG0AYQB5ACAAYgBlACAAcgBlAGcAaQBzAHQAZQByAGUAZAAgAGkAbgAgAGMAZQByAHQAYQBpAG4AIABqAHUAcgBpAHMAZABpAGMAdABpAG8AbgBzAC4ASABvAGUAZgBsAGUAcgAgACYAIABDAG8ALgBUAGgAaQBzACAAcwBvAGYAdAB3AGEAcgBlACAAaQBzACAAdABoAGUAIABwAHIAbwBwAGUAcgB0AHkAIABvAGYAIABIAG8AZQBmAGwAZQByACAAJgAgAEMAbwAuACAAWQBvAHUAIABtAGEAeQAgAG4AbwB0ACAAYwBvAHAAeQAsACAAbQBvAGQAaQBmAHkALAAgAGQAaQBzAHQAcgBpAGIAdQB0AGUALAAgAG8AcgAgAGQAbwB3AG4AbABvAGEAZAAgAHQAaABpAHMAIABzAG8AZgB0AHcAYQByAGUALAAgAG8AcgAgAGkAbgBzAHQAYQBsAGwAIABpAHQAIAB1AHAAbwBuACAAYQBuAHkAIABjAG8AbQBwAHUAdABlAHIALAAgAG8AcgAgAGgAbwBzAHQAIABpAHQAIABmAHIAbwBtACAAYQBuAHkAIABsAG8AYwBhAHQAaQBvAG4ALgAgAFkAbwB1AHIAIAByAGkAZwBoAHQAIAB0AG8AIAB1AHMAZQAgAHQAaABpAHMAIABzAG8AZgB0AHcAYQByAGUAIABpAHMAIABzAHUAYgBqAGUAYwB0ACAAdABvACAAdABoAGUAIABUAGUAcgBtAHMAIABvAGYAIABTAGUAcgB2AGkAYwBlACAAYQBnAHIA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); font-weight:300; font-style:normal; } \ No newline at end of file diff --git a/docs/static/fonts/332720/52C563F8BC21B4B43.css b/docs/static/fonts/332720/52C563F8BC21B4B43.css deleted file mode 100644 index 33716adc57..0000000000 --- a/docs/static/fonts/332720/52C563F8BC21B4B43.css +++ /dev/null @@ -1,19 +0,0 @@ - -/* - Copyright (C) 2011-2015 Hoefler & Co. - This software is the property of Hoefler & Co. (H&Co). - Your right to access and use this software is subject to the - applicable License Agreement, or Terms of Service, that exists - between you and H&Co. If no such agreement exists, you may not - access or use this software for any purpose. - This software may only be hosted at the locations specified in - the applicable License Agreement or Terms of Service, and only - for the purposes expressly set forth therein. You may not copy, - modify, convert, create derivative works from or distribute this - software in any way, or make it accessible to any third party, - without first obtaining the written permission of H&Co. - For more information, please visit us at http://typography.com. - 171247-88474-20150623 -*/ - -@font-face { font-family:"Gotham Rounded A"; src: url('http://nuclide.io/static/fonts/332720/78E7259F6E64A8FDC.eot'); src: url('http://nuclide.io/static/fonts/332720/78E7259F6E64A8FDC.eot?#hfj') format('embedded-opentype'); font-style:normal; font-weight:300; } @font-face { font-family:"Gotham Rounded 3r"; src: url('http://nuclide.io/static/fonts/332720/78E7259F6E64A8FDC.eot'); src: url('http://nuclide.io/static/fonts/332720/78E7259F6E64A8FDC.eot?#hfj') format('embedded-opentype'); font-style:normal; font-weight:300; } \ No newline at end of file diff --git a/docs/static/fonts/332720/537C133D913A8D41D.css b/docs/static/fonts/332720/537C133D913A8D41D.css deleted file mode 100644 index 28e5ff0939..0000000000 --- a/docs/static/fonts/332720/537C133D913A8D41D.css +++ /dev/null @@ -1,19 +0,0 @@ - -/* - Copyright (C) 2011-2015 Hoefler & Co. - This software is the property of Hoefler & Co. (H&Co). - Your right to access and use this software is subject to the - applicable License Agreement, or Terms of Service, that exists - between you and H&Co. If no such agreement exists, you may not - access or use this software for any purpose. - This software may only be hosted at the locations specified in - the applicable License Agreement or Terms of Service, and only - for the purposes expressly set forth therein. You may not copy, - modify, convert, create derivative works from or distribute this - software in any way, or make it accessible to any third party, - without first obtaining the written permission of H&Co. - For more information, please visit us at http://typography.com. - 171247-88474-20150623 -*/ - -@font-face{ font-family: "Gotham Rounded A"; src: url(data:font/truetype;base64,egABAAEAPz8GAAEAAQAAAAEAAAABAHoAAQAEAAEAegABAAEADgABAAgAAQAoAAEAAAABABAAAQAAAAYADgAGAAIAAAABAAAACAAxMHNzAQAAAAEAPz8AAAAABAAAAAEAPz8AAAAABAAaAG50YWwOAFRMRkQCAD4AMAAKAAAAAQAAAAMAAQABAAAAAQAIAAEARQB3AHUAOwBzAGoAOgBlAGUAMABcAFMALABRAE4AKwBMAEwAJwBJAEYAJABEAEIAFgA/ADIAEwAvAC0ADAAqACQACQAeABwACAAaABoAAwATAA8AAgANAA0AAQALAAsAAAAJAAkAEQACACYAAAAcABsAFwAAABUAJQAkABUAJQAkABgAGAAjABwAAAAAAAAAJgAbAAAAAAAAAAAAAAAAABEAAAAAADEAMAAvAC4ALQAsACoAJwAfABYAHwATAB8AHwAPAA8AHgAdAA8AGgAZABMAFgATAA8ADAAAABIAEAAAAAsACgAJAAgABwAGAAUABAAAAAIAAAACAAAAAAAAAAAAAwAAAAAAAgAAAAAAAAACAAAAAQAAACIAAAAAAAAAFAAUAAAAAAAoAAAAAAAAACsAAAAgADIAKQAXABgAFQAAAA4AIQAAAAAADQBxAAkAAQAnACYAIgAAACAALwAuACAALwAuACMAIwAtACcAAAAAAAAAAAAmAAAAAAAAAAAAAAAAAAAAAAAcADoAOQA4ADcANgA1ADQAMQAwAAAAGgArACgAKAAAACkAAAAAACgAJQAkACEAAAAeABoAFwAAAAAAGwAdABYAFQAUABMAEgARABAADwAOAA0ADAALAAAAAAAKAAkACAAAAAAABwAGAAUABAADAAIAAQAAAAAAAAAAAAAAHwAfACoAAAAyAAAAAAAAAAAAAAAAADsAMwAiACMAIAAAABkAAAAsAAAAGABvAAkAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/PwAAPz8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPz8/AAAAAAAAPz8AAAAAPz8AAAAAPz8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPz8/Pz8/PwAAAAAAAD8/AAA/PwAAAAAAAAAAPz8AAAAAAAAAAAAAPz8/PwAAPz8/Pz8/AAA/Pz8/Pz8AAAAAAAA/PwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/PwAAPz8AAAAAAAAAAAAAAAA/PwAAAAAAAAAAAAAAAAAAAAAAAAAAPz8/PwAAPz8AAD8/AAAAAD8/AAAAAAAAAAAAAAAAPz8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD8/Pz8/Pz8AAAAAAAA/PwAAPz8AAAAAAAAAAD8/AAAAAAAAAAAAAD8/PwAAPz8/Pz8/AAA/Pz8/Pz8AAAAAAAA/PwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPz8AAD8/AAAAAAAAAAAAAAAAPz8AAAAAAAAAAAAAAAAAAAAAAAAAAD8/Pz8AAD8/Pz8/PwAAPz8AAAAAAAAAAAAAAAA/PwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPz8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACgAAAAAAAAAAAAAAAAAAAAAAAAA/PwAAAAAAAD8/AAAAAD8/AAAAAD8/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD8/PwAAPz8AAD8/AAA/PwAAAAA/PwAAAAAAAAAAAAAAAAAAPz8AAAAAAAAAAD8/AAAAAD8/AAAAAD8/AAAAAAAAAAAAAAAAPz8AAAAAAAAAAAAAAAA/PwAAPz8/PwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD8/Pz8AAD8/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/Pz8/PwAAAAA/PwAAAAA/PwAAAAA/PwAAPz8/AAAAAAAAAAAAAD8/AAAAAAAAAAAAAAAAAAAAAD8/Pz8/PwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/PwAAAAAAAAAAAAAAAAAAPz8AAAAAAAAjABQAAAAAAAAAAAAAAAAAAAAAAD8/AAAAAD8/Pz8AAD8/AAAAAD8/AAAUAAAAPz8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPz8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/PwAAAAAAAD8/AAAAAD8/AAAAAAAAAAAAAAAAPz8AAAAAAAAAAAAAAAAAAAAAPz8AAD8/AAAAAD8/AAAAAAAAAAAAAAAADwAAAAAAPz8AAAAAAAA/PwAAAAAAAAAAAAAAAAAAAAA/PwAAAAAAAD8/AAAAAD8/AAAAAAAAAAAAAAAAPz8AAAAAAAAAAAAAAAAAAAAAPz8AAD8/AAAAAAAAPz8AAD8/AAAAAAAAPz8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD8/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACgAAAD8/AAA/PwAAPz8/AAAAAD8/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/PwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD8/AAAAAAAAPz8AAAAAPz8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD8/AAAAAAAAPz8/Pz8/AAAAAAAAAAAAAAAAAAAAAD8/AAA/Pz8AAAAAAAAAAD8/AAAAAAAAAAA/PwAAPz8AAAAAPz8/Pz8AAD8/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD8/AAA/PwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/PwAAPz8/Pz8AAD8/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/Pz8AAD8/AAA/PwAAAAA/PwAAAAA/PwAAAAAAAD8/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD8/AAA/Pz8AAAAAAAAAAAAAAAAAAAAAAAAAAD8/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD8/AAA/PwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD8/Pz8/PwAAAAA/PwAAAAA/PwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPz8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD8/Pz8/Pz8AAD8/Pz8AAAAAPz8AAAAAAAA/Pz8/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPz8AAAAAAAA/PwAAAAA/PwAAAAAAAAAAAAAAAAAAAAA/Pz8/AAA/PwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD8/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD8/AAAAAAAAAAAAAAAAAAA/PwAAAAA3ACMAHgAAACMAHgAAAAAAAAAAAAAAPz8/PwAAAAA/Pz8/PwAAPz8UAB4AHgAAAB4AAAA/PwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPz8/PwAAPz8AAAAAPz8AAAAAAAAAAAAAAAAAAD8/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD8/Pz8/Pz8AAD8/AAAAAAAAPz8AAD8/AAA/PwAAPz8/PwAAAAA/PwAAPz8AAAAAPz8AAAAAAAAAAD8/AAAAAAAAAAAAAD8/AAAAAD8/AAAAAD8/AAAAAAAAAAAAAAAAAAAAAH4/AAA/Pz8/PwAAAAA/PwAAAAAAAD8/Pz8/PwAAAAAAAAAAAAAAAAAAAAAAAAAAPz8/AAAAAAAAAAAAAAAAAAAAAAAAPz8AAD8/AAAAAD8/Pz8/PwAAPz8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPz8AAD8/AAA/Pz8/AAAAAD8/AAA/PwAAAAA/PwAAAAAAAAAAPz8AAA8AAAAAAAAAPz8AAAAAPz8AAAAAPz8AAAAAAAAAAAAAAAAAAAAAfj8AAD8/Pz8/AAAAAD8/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPz8AAD8/PwAAPz8AAAAAAAAAAAAAAAAAAD8/Pz8/Pz8/AAAAAAAAAAAAAAAAAAAPAAoAAAA/Pz8AAAAAAAAAAAoAPz8/PwAAAAAAAD8/AAAAAD8/AAAAAD8/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPz8AAD8/AAAAAAAAAAAAAAAAPz8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD8/AAAAAD8/AAAAAAAAAAAAAAAAPz8AAAAAAAAAAAAAAAAAAAAAAAA/PwAAAAAAAD8/Pz8AAD8/AAAAAAAAAAAAAAAAPz8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/PwAAAAAAAD8/AAAAAD8/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/PwAAAAAAAAAAPz8AAD8/AAAAAAAAPz8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD8/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD8/AAA/PwAAPz8/PwAAAAA/PwAAAAAAAD8/Pz8/PwAAAAAAAAAAAAAAAAAAAAA/PwAAPz8/AAAAAAAAAAA/PwAAAAAAAAAAPz8AAD8/AAAAAD8/Pz8/AAA/PwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACgAAAAAAPz8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/PwAAAAAAAD8/AAAAAD8/AAAAAAAAAAAAAAAAPz8AAAAAAAAAAAAAAAAAAAAAAAAAAD8/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD8/AAA/PwAAAAA/Pz8/AAAAAAAAAAAAAAAAPz8AAD8/PwAAAAA/PwAAAAAAAAAAAAAAAAAAPz8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPz8AAD8/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/PwAAPz8/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD8/Pz8/AAA/PwAAAAA/PwAAAAAAAAAAAAA/PwAAPz8AAAAAAAAAAAAAAAA/PwAAPz8AAAAAAAA/Pz8/Pz8/Pz8AAD8/Pz8AAD8/AAAAAAAAAAAAAAAAAAA/Pz8/Pz8/Pz8/Pz9+Pz8/fj8/Pz8AAAAAAAA/PwAAPz8/Pz8/AAA/Pz8/AAAAAD8/fj8/Pz8AAAAAAAA/PwAAPz8AAD8/AAA/PwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD8/Pz8/PwAAPz8AAAAAPz8AAAAAAAA/PwAAAAA/PwAAPz8AAD8/AAA/PwAAPz8AAD8/AAAAAAAAPz8/Pz8/PwAAPz8/PwAAPz8AAAAAAAAAAAAAAAAAAD8/Pz8/Pz8/Pz8/Pz8/PwAAAAAAAD8/AAA/Pz8/Pz8/Pz8/PwAAAAA/Pz8/Pz8/AAAAAD8/PwAAPz8AAD8/AAA/PwAAAAA/PwAAAAAAAAAAAAAAAAAAPz8AAD8/Pz8/Pz8/Pz8/Pz8/PwAAAAAAAD8/AAAAAD8/Pz8AAD8/AAAAAAAAPz8AAD8/Pz8AAAAAAAAAAD8/AAAAAAAAAAAAAD8/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD8/AAA/PwAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/PwAAAAAAAAAAAAA/PwAAPz8AAAAAPz8/Pz8/Pz8/Pz8/AAA/Pz8/AAA/PwAAAAAAAAAAAAAAAAAAPz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz95PwAAAAAAAD8/AAA/P3k/PwAAAAAAAAAAAAAAAD8/Pz8/Pz8AAAAAPz8/PwAAAAA/PwAAAAAAAAAAAAAAAAAAPz8AAAAAAAAAAAAAAAAAAAAAPz8AAAAAAAAAAAAAAAAAAAAAPz8AAAAAAAAAAD8/Pz8/AAA/Pz8/AAAAAD8/AAAAAAAAAAAAAAAAAAAAAAAACgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/PwoAAAAAAD8/AAAAAD8/AAAAAAAAAAAAAAAAAAAAAD8/AAA/Pz8AAD8/AAA/PwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPz8AAD8/AAAAAD8/AAAAAAAAAAAAAAAAAAAKAAAACgAAAAUAAAAPAAAAAAAAAAAAFAAAAAAAAAAAAAAAAAAAAAAAAAAKAAAADwAAAD8/AAA/PwAAPz8AAAAAAAAAAAAAAAA/Pz8/AAA/PwAAAAAAAAAAAAAAAD8/AAAAAAAAAAA/PwAAAAAAAAAAAAA/PwAAAAAAAAAAAAAAAD8/PwAAAAAAAAAAAAAAAAAAAAAAAD8/AAA/PwAAAAA/Pz8/AAAAAAAAAAA/Pz8/Pz8AAD8/Pz8AAD8/AAAAAAAAPz8AAD8/PwAAAAA/PwAAAAAAAD8/Pz8AAD8/AAAAAAAAAAAAAAAAAAA/Pz8AAD8/AAAAAD8/AAAAAD8/AAA/Pz8/AAAAAH4/AAA/Pz8/Pz8AAAAAPz8AAAAAAAAAAD8/AAA/Pz8/AAA/PwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/Pz8/PwAAPz8AAAAAPz8AAAAAAAAAAAAAPz8/PwAAPz8AAD8/Pz8/Pz8/AAA/PwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/PwAAPz8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD8/AAAAAAAAPz8AAAAAPz8AAAAAAAAAAAAAAAAAAAAAAAAAAD8/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD8/AAAAAAAACgAAAD8/Pz8AAD8/AAAAAAAAAAAAAAAAPz8/AAA/PwAAAAAAAAAAAAAAAD8/AAAUAAAAAAAAAAAAAAAAAAAAAAA/PwAAPz8AAAAAPz8/Pz8/AAA/PwAAAAAAAAAAAAAAAD8/Pz8AAAAAAAAAAAAAAAAAAAAAPz8/PwAAAAAAAD8/AAA/Pz8/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/PwAAAAA/PwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPz8AAAAAAAAAAAAAPz8AAAAAAAAAAAAAAAA/Pz8AAAAAAAAAAAAAAAAAAAAAAAA/PwAAPz8AAAAAPz8/PwAAAAAAAAAAPz8/Pz8/PwAAPz8/Pz8AAD8/AAAAAAAAPz8/Pz8/Pz8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/PwAAPz8AAD8/AAAAAD8/AAAAAAAAAAAAAAAAAAAAAD8/Pz8AAAAAAAAA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AHkAdAAuAHcAdwB3AC8ALwA6AHAAdAB0AGgAIAB0AGkAcwBpAHYAIABlAHMAYQBlAGwAcAAgACwAbgBvAGkAdABhAG0AcgBvAGYAbgBpACAAZQByAG8AbQAgAHIAbwBGACAALgBlAHMAbwBwAHIAdQBwACAAeQBuAGEAIAByAG8AZgAgAGUAcgBhAHcAdABmAG8AcwAgAHMAaQBoAHQAIABlAHMAdQAgAHQAbwBuACAAeQBhAG0AIAB1AG8AeQAgACwAcwB0AHMAaQB4AGUAIAB0AG4AZQBtAGUAZQByAGcAYQAgAGgAYwB1AHMAIABvAG4AIABmAEkAIAAuAG8AQwAgACYAIAByAGUAbABmAGUAbwBIACAAZABuAGEAIAB1AG8AeQAgAG4AZQBlAHcAdABlAGIAIABzAHQAcwBpAHgAZQAgAHQAYQBoAHQAIAB0AG4AZQBtAGUAZQByAGcAYQAgAGUAYwBpAHYAcgBlAFMAIABmAG8AIABzAG0AcgBlAFQAIABlAGgAdAAgAG8AdAAgAHQAYwBlAGoAYgB1AHMAIABzAGkAIABlAHIAYQB3AHQAZgBvAHMAIABzAGkAaAB0ACAAZQBzAHUAIABvAHQAIAB0AGgAZwBpAHIAIAByAHUAbwBZACAALgBuAG8AaQB0AGEAYwBvAGwAIAB5AG4AYQAgAG0AbwByAGYAIAB0AGkAIAB0AHMAbwBoACAAcgBvACAALAByAGUAdAB1AHAAbQBvAGMAIAB5AG4AYQAgAG4AbwBwAHUAIAB0AGkAIABsAGwAYQB0AHMAbgBpACAAcgBvACAALABlAHIAYQB3AHQAZgBvAHMAIABzAGkAaAB0ACAAZABhAG8AbABuAHcAbwBkACAAcgBvACAALABlAHQAdQBiAGkAcgB0AHMAaQBkACAALAB5AGYAaQBkAG8AbQAgACwAeQBwAG8AYwAgAHQAbwBuACAAeQBhAG0AIAB1AG8AWQAgAC4AbwBDACAAJgAgAHIAZQBsAGYAZQBvAEgAIABmAG8AIAB5AHQAcgBlAHAAbwByAHAAIABlAGgAdAAgAHMAaQAgAGUAcgBhAHcAdABmAG8AcwAgAHMAaQBoAFQALgBvAEMAIAAmACAAcgBlAGwAZgBlAG8ASAAuAHMAbgBvAGkAdABjAGkAZABzAGkAcgB1AGoAIABuAGkAYQB0AHIAZQBjACAAbgBpACAAZABlAHIAZQB0AHMAaQBnAGUAcgAgAGUAYgAgAHkAYQBtACAAaABjAGkAaAB3ACAALAAuAG8AQwAgACYAIAByAGUAbABmAGUAbwBIACAAZgBvACAAawByAGEAbQBlAGQAYQByAHQAIABhACAAcwBpACAAbQBhAGgAdABvAEcAdABuAG8ARgAxADAAMwAuADEAIABuAG8AaQBzAHIAZQBWADkAMQAyADAANAAxAC0AMwAyADQAMgAtADMAMgA2ADAANQAxADAAMgAtADQANwA0ADgAOAAtADcANAAyADEANwAxAHIAYQBsAHUAZwBlAFIAbQBvAGMALgB5AGgAcABhAHIAZwBvAHAAeQB0ACAAfAAgAG8AQwAmAEgAIAApAEMAKAAgAHQAaABnAGkAcgB5AHAAbwBDAG0AbwBjAC4AeQBoAHAAYQByAGcAbwBwAHkAdAAuAHcAdwB3AC8ALwA6AHAAdAB0AGgAIAAuAG8AQwAgACYAIAByAGUAbABmAGUAbwBIACAANwAwADAAMgAgACwANgAwADAAMgAgACkAQwAoACAAdABoAGcAaQByAHkAcABvAEMAZXJhd3Rmb3MtdG5vZmJldy9tb2MueWhwYXJnb3B5dC53d3cvLzpwdHRobW9jLnlocGFyZ29weXQud3d3OTEyMDQxLTMyNDItMzI2MDUxMDItNDc0ODgtNzQyMTcxIG1vYy55aHBhcmdvcHl0Lnd3dyB0YSAub0MgJiByZWxmZW9IIHRjYXRub2Mgcm8gLGVyYXd0Zm9zLXRub2ZiZXcvbW9jLnlocGFyZ29weXQud3d3Ly86cHR0aCB0aXNpdiBlc2FlbHAgLG5vaXRhbXJvZm5pIGVyb20gcm9GIC5lc29wcnVwIHluYSByb2YgZXJhd3Rmb3Mgc2lodCBlc3UgdG9uIHlhbSB1b3kgLHN0c2l4ZSB0bmVtZWVyZ2EgaGN1cyBvbiBmSSAub0MgJiByZWxmZW9IIGRuYSB1b3kgbmVld3RlYiBzdHNpeGUgdGFodCB0bmVtZWVyZ2EgZWNpdnJlUyBmbyBzbXJlVCBlaHQgb3QgdGNlamJ1cyBzaSBlcmF3dGZvcyBzaWh0IGVzdSBvdCB0aGdpciBydW9ZIC5ub2l0YWNvbCB5bmEgbW9yZiB0aSB0c29oIHJvICxy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)); font-weight:300; font-style:normal; } \ No newline at end of file diff --git a/docs/static/fonts/332720/695AC8DE58C109BF3.css b/docs/static/fonts/332720/695AC8DE58C109BF3.css deleted file mode 100644 index 206532f78a..0000000000 --- a/docs/static/fonts/332720/695AC8DE58C109BF3.css +++ /dev/null @@ -1,19 +0,0 @@ - -/* - Copyright (C) 2011-2015 Hoefler & Co. - This software is the property of Hoefler & Co. (H&Co). - Your right to access and use this software is subject to the - applicable License Agreement, or Terms of Service, that exists - between you and H&Co. If no such agreement exists, you may not - access or use this software for any purpose. - This software may only be hosted at the locations specified in - the applicable License Agreement or Terms of Service, and only - for the purposes expressly set forth therein. You may not copy, - modify, convert, create derivative works from or distribute this - software in any way, or make it accessible to any third party, - without first obtaining the written permission of H&Co. - For more information, please visit us at http://typography.com. - 171247-88474-20150623 -*/ - -@font-face{ font-family: "Gotham Rounded A"; src: url(data:application/x-font-woff;base64,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); font-weight:300; font-style:normal; } \ No newline at end of file diff --git a/docs/static/fonts/332720/740083249BEF005F6.css b/docs/static/fonts/332720/740083249BEF005F6.css deleted file mode 100644 index 4aeacc5add..0000000000 --- a/docs/static/fonts/332720/740083249BEF005F6.css +++ /dev/null @@ -1,19 +0,0 @@ - -/* - Copyright (C) 2011-2015 Hoefler & Co. - This software is the property of Hoefler & Co. (H&Co). - Your right to access and use this software is subject to the - applicable License Agreement, or Terms of Service, that exists - between you and H&Co. If no such agreement exists, you may not - access or use this software for any purpose. - This software may only be hosted at the locations specified in - the applicable License Agreement or Terms of Service, and only - for the purposes expressly set forth therein. You may not copy, - modify, convert, create derivative works from or distribute this - software in any way, or make it accessible to any third party, - without first obtaining the written permission of H&Co. - For more information, please visit us at http://typography.com. - 171247-88474-20150623 -*/ - -@font-face{ font-family: "Gotham Rounded A"; src: url(data:font/opentype;base64,T1RUTwANAIAAAwBQQ0ZGIKWnUnEAABFoAAAs60dERUYApgAEAAA+VAAAACBHUE9T5Gif/gAAPnQAAB1aR1NVQunbLV4AAFvQAAAAgE9TLzJVxSTvAAABQAAAAGBjbWFwaLtaTgAADVwAAAPsZ2FzcAAAAAsAAFxQAAAACGhlYWQDcke8AAAA3AAAADZoaGVhB74DwAAAARQAAAAkaG10eAmBHxsAAFxYAAAB5G1heHAAeVAAAAABOAAAAAZuYW1lKDUzBAAAAaAAAAu7cG9zdP+4ADIAABFIAAAAIAABAAAAAQBByTlTkF8PPPUACwPoAAAAANAsAh4AAAAA0CwCHv/o/zgEEwMiAAAACAACAAAAAAAAAAEAAAPA/xAAAARO/+j/6AQTAAEAAAAAAAAAAAAAAAAAAAB5AABQAAB5AAAAAgHwASwABQAEArwCigAAAIwCvAKKAAAB3QAyAPoAAAAAAAAAAAAAAACgAAB/UAAASgAAAAAAAAAASCZDbwAAACLgEgMg/zgAyAPAAPAAAAALAAAAAAH+ArwAIAAgAAIAAAAkAbYAAQAAAAAAAABAAAAAAQAAAAAAAQAjAEAAAQAAAAAAAgAHAGMAAQAAAAAAAwAhAGoAAQAAAAAABAAjAEAAAQAAAAAABQANAIsAAQAAAAAABgAEAJgAAQAAAAAABwBhAJwAAQAAAAAACAANAP0AAQAAAAAACQANAP0AAQAAAAAACgIRAQoAAQAAAAAACwASAxsAAQAAAAAADAASAxsAAQAAAAAADQIRAQoAAQAAAAAADgAqAy0AAQAAAAAAEAAjAEAAAQAAAAAAEQAjAEAAAQAAAAAAEgAjAEAAAwABBAkAAACAA1cAAwABBAkAAQBGA9cAAwABBAkAAgAOBB0AAwABBAkAAwBCBCsAAwABBAkABABGA9cAAwABBAkABQAaBG0AAwABBAkABgAIBIcAAwABBAkABwDCBI8AAwABBAkACAAaBVEAAwABBAkACQAaBVEAAwABBAkACgQiBWsAAwABBAkACwAkCY0AAwABBAkADAAkCY0AAwABBAkADQQiBWsAAwABBAkADgBUCbEAAwABBAkAEABGA9cAAwABBAkAEQBGA9cAAwABBAkAEgBGA9dDb3B5cmlnaHQgKEMpIDIwMDYsIDIwMDcgSG9lZmxlciAmIENvLiBodHRwOi8vd3d3LnR5cG9ncmFwaHkuY29tQ29weXJpZ2h0IChDKSBIJkNvIHwgdHlwb2dyYXBoeS5jb21SZWd1bGFyMTcxMjQ3LTg4NDc0LTIwMTUwNjIzLTI0MjMtMTQwMjE5VmVyc2lvbiAxLjIwMUZvbnRHb3RoYW0gUm91bmRlZCBpcyBhIHRyYWRlbWFyayBvZiBIb2VmbGVyICYgQ28uLCB3aGljaCBtYXkgYmUgcmVnaXN0ZXJlZCBpbiBjZXJ0YWluIGp1cmlzZGljdGlvbnMuSG9lZmxlciAmIENvLlRoaXMgc29mdHdhcmUgaXMgdGhlIHByb3BlcnR5IG9mIEhvZWZsZXIgJiBDby4gWW91IG1heSBub3QgY29weSwgbW9kaWZ5LCBkaXN0cmlidXRlLCBvciBkb3dubG9hZCB0aGlzIHNvZnR3YXJlLCBvciBpbnN0YWxsIGl0IHVwb24gYW55IGNvbXB1dGVyLCBvciBob3N0IGl0IGZyb20gYW55IGxvY2F0aW9uLiBZb3VyIHJpZ2h0IHRvIHVzZSB0aGlzIHNvZnR3YXJlIGlzIHN1YmplY3QgdG8gdGhlIFRlcm1zIG9mIFNlcnZpY2UgYWdyZWVtZW50IHRoYXQgZXhpc3RzIGJldHdlZW4geW91IGFuZCBIb2VmbGVyICYgQ28uIElmIG5vIHN1Y2ggYWdyZWVtZW50IGV4aXN0cywgeW91IG1heSBub3QgdXNlIHRoaXMgc29mdHdhcmUgZm9yIGFueSBwdXJwb3NlLiBGb3IgbW9yZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpc2l0IGh0dHA6Ly93d3cudHlwb2dyYXBoeS5jb20vd2ViZm9udC1zb2Z0d2FyZSwgb3IgY29udGFjdCBIb2VmbGVyICYgQ28uIGF0IHd3dy50eXBvZ3JhcGh5LmNvbSAxNzEyNDctODg0NzQtMjAxNTA2MjMtMjQyMy0xNDAyMTl3d3cudHlwb2dyYXBoeS5jb21odHRwOi8vd3d3LnR5cG9ncmFwaHkuY29tL3dlYmZvbnQtc29mdHdhcmUAQwBvAHAAeQByAGkAZwBoAHQAIAAoAEMAKQAgADIAMAAwADYALAAgADIAMAAwADcAIABIAG8AZQBmAGwAZQByACAAJgAgAEMAbwAuACAAaAB0AHQAcAA6AC8ALwB3AHcAdwAuAHQAeQBwAG8AZwByAGEAcABoAHkALgBjAG8AbQBDAG8AcAB5AHIAaQBnAGgAdAAgACgAQwApACAASAAmAEMAbwAgAHwAIAB0AHkAcABvAGcAcgBhAHAAaAB5AC4AYwBvAG0AUgBlAGcAdQBsAGEAcgAxADcAMQAyADQANwAtADgAOAA0ADcANAAtADIAMAAxADUAMAA2ADIAMwAtADIANAAyADMALQAxADQAMAAyADEAOQBWAGUAcgBzAGkAbwBuACAAMQAuADIAMAAxAEYAbwBuAHQARwBvAHQAaABhAG0AIABSAG8AdQBuAGQAZQBkACAAaQBzACAAYQAgAHQAcgBhAGQAZQBtAGEAcgBrACAAbwBmACAASABvAGUAZgBsAGUAcgAgACYAIABDAG8ALgAsACAAdwBoAGkAYwBoACAAbQBhAHkAIABiAGUAIAByAGUAZwBpAHMAdABlAHIAZQBkACAAaQBuACAAYwBlAHIAdABhAGkAbgAgAGoAdQByAGkAcwBkAGkAYwB0AGkAbwBuAHMALgBIAG8AZQBmAGwAZQByACAAJgAgAEMAbwAuAFQAaABpAHMAIABzAG8AZgB0AHcAYQByAGUAIABpAHMAIAB0AGgAZQAgAHAAcgBvAHAAZQByAHQAeQAgAG8AZgAgAEgAbwBlAGYAbABlAHIAIAAmACAAQwBvAC4AIABZAG8AdQAgAG0AYQB5ACAAbgBvAHQAIABjAG8AcAB5ACwAIABtAG8AZABpAGYAeQAsACAAZABpAHMAdAByAGkAYgB1AHQAZQAsACAAbwByACAAZABvAHcAbgBsAG8AYQBkACAAdABoAGkAcwAgAHMAbwBmAHQAdwBhAHIAZQAsACAAbwByACAAaQBuAHMAdABhAGwAbAAgAGkAdAAgAHUAcABvAG4AIABhAG4AeQAgAGMAbwBtAHAAdQB0AGUAcgAsACAAbwByACAAaABvAHMAdAAgAGkAdAAgAGYAcgBvAG0AIABhAG4AeQAgAGwAbwBjAGEAdABpAG8AbgAuACAAWQBvAHUAcgAgAHIAaQBnAGgAdAAgAHQAbwAgAHUAcwBlACAAdABoAGkAcwAgAHMAbwBmAHQAdwBhAHIAZQAgAGkAcwAgAHMAdQBiAGoAZQBjAHQAIAB0AG8AIAB0AGgAZQAgAFQAZQByAG0AcwAgAG8AZgAgAFMAZQByAHYAaQBjAGUAIABhAGcAcgBlAGUAbQBlAG4AdAAgAHQAaABhAHQAIABlAHgAaQBzAHQAcwAgAGIAZQB0AHcAZQBlAG4AIAB5AG8AdQAgAGEAbgBkACAASABvAGUAZgBsAGUAcgAgACYAIABDAG8ALgAgAEkAZgAgAG4AbwAgAHMAdQBjAGgAIABhAGcAcgBlAGUAbQBlAG4AdAAgAGUAeABpAHMAdABzACwAIAB5AG8AdQAgAG0AYQB5ACAAbgBvAHQAIAB1AHMAZQAgAHQAaABpAHMAIABzAG8AZgB0AHcAYQByAGUAIABmAG8AcgAgAGEAbgB5ACAAcAB1AHIAcABvAHMAZQAuACAARgBvAHIAIABtAG8AcgBlACAAaQBuAGYAbwByAG0AYQB0AGkAbwBuACwAIABwAGwAZQBhAHMAZQAgAHYAaQBzAGkAdAAgAGgAdAB0AHAAOgAvAC8AdwB3AHcALgB0AHkAcABvAGcAcgBhAHAAaAB5AC4AYwBvAG0ALwB3AGUAYgBmAG8AbgB0AC0AcwBvAGYAdAB3AGEAcgBlACwAIABvAHIAIABjAG8AbgB0AGEAYwB0ACAASABvAGUAZgBsAGUAcgAgACYAIABDAG8ALgAgAGEAdAAgAHcAdwB3AC4AdAB5AHAAbwBnAHIAYQBwAGgAeQAuAGMAbwBtACAAMQA3ADEAMgA0ADcALQA4ADgANAA3ADQALQAyADAAMQA1ADAANgAyADMALQAyADQAMgAzAC0AMQA0ADAAMgAxADkAdwB3AHcALgB0AHkAcABvAGcAcgBhAHAAaAB5AC4AYwBvAG0AaAB0AHQAcAA6AC8ALwB3AHcAdwAuAHQAeQBwAG8AZwByAGEAcABoAHkALgBjAG8AbQAvAHcAZQBiAGYAbwBuAHQALQBzAG8AZgB0AHcAYQByAGUAAAAAAwAAAAMAAAAcAAEAAAAAAuYAAwABAAAAHAAEAsoAAABYAEAABQAYAF0AXwB9AKMApQCrAK4AsAC3ALsAxQDPANYA3QDlAO8A9gD9AQcBGwEjAScBMQE3AUgBUQFbAWUBfgH7Af8CGR6FHvMgFCAaIB4gIiAmIDogrCEi4BL//wAAACAAXwBhAKEApQCpAK4AsAC3ALoAvwDHANEA2ADgAOcA8QD4AP8BCgEeASYBKgE2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AAD/9gAAAAAAAAAA/+wAAAAAAAAAAAAAAAD/9v/2AAAAAAAAAAAAAAAAAAAAAP/2AAAAAP/2AAD/9gAA//YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/9v/2//b/9gAAAAAAAP/TAAD/2P/2/8kAAP/T/93/yf+//9MAAAAAAAAAAP/Y/+z/7AAAAAD/2AAA/9gAAAAAAAAAAAAAAAAAAAAAAAD/4v/sAAAAAAAAAAAAAAAA/9gAAAAAAAAAAAAA//YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/2AAAAAP/2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/9v/2AAD/9gAAAAAAAP+w/+wAAAAAAAAAAAAAAAAAAAAA//b/5wAAAAAAAAAAAAAAAP/xAAD/nP/2/5wAAAAA//YAAP/xAAAAAAAAAAAAAAAAAAAAAAAUAAD/9gAAAAAAAAAAAAAAAP/2AAD/8f/xAAAAAAAAAAAAAAAA/+wAAP/s//H/9v/iAAAACgAAAAAAAP/xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/2AAAAAAAAAAAAAAAAAAAAAAAAAAD/+wAAAAD/+wAAAAAAAP/nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/8QAA//EAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/84AAP/2//b/8f/i/+IAAP/YAAD/9v/2AAAAAAAAAAAAAP/iAAAAAP/nAAD/zv/s/+f/7AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/5wAA/+z/xP/OAAD/zgAAAAAAAAAA/9gAAAAA/5z/7P+N/5wAAP9+AAAAAP/2/7AAAP+IAAAAAP/2AAAAAP/7AAD/2P/s//sAAAAAAAAAAAAAAAAAAP/EAAD/2P/Y/6YAAAAAAAD/7AAAAAD/xP/OAAD/xAAAAAAAAP/YAAD/4v/7/8kAAP/Y/93/zv/E/9gAAAAAAAAAAP/Y/+z/7AAAAAD/2AAA/9gAAAAAAAAAAAAAAAAAAAAAAAD/4v/sAAAAAAAAAAAAAAAA/9gAAAAAAAAAAAAA//sAAAAAAAAAAP+6AAAAAAAAAAAAAAAA//sAAP/2//H/9gAAAAAAAAAAAAAAAP/7AAD/nAAA/5wAAAAPAAAACgAAAAAAAAAAAAAAAAAAAAAAAAAUAAAAAAAAAAAADwAAAAUAAAAKAAAACgAAAAAAAAAAAAAAAAAA/8kAAAAA/90AAP+/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/+wAA//YAAP/s//EAAP/nAAAAAAAAAAAAAAAAAAAAAP/2AAAAAP/7AAAAAAAK//sAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACgAAAAAAAAAAAAAAAAAAAAAAAP/xAAAAAP/2//EAAP/i/+f/5//i//YAAAAAAAAAAP/sAAAAAAAAAAAAAAAAAAAAAP/7AAAAAAAAAAAAAAAAAAAAAP/2AAAAAAAAAAAAAAAAAAD/+wAAAAD/8f/2//H/8f/7AAAAAP+m/8n/kv/xAAAAAAAAAAAAAAAA/+z/ef+6AAD/7AAAAAAAAP95/87/nP+D/5z/pv/O/4P/pv+6/9j/2P+cAAAAAAAAAAAAAAAAAAD/jQAA/6b/zgAA/5z/nP+c/5z/nP+SAAAAAP/nAAD/7AAAAAAAAAAAAAD/9gAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/8QAA//EAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//EAAAAAAAAAAAAA//sAAAAAAAAAAP+c/9gAAP/nAAAAAAAA//YAAP/s//b/ugAAAAD/9gAAAAAAAP+6/+z/iP+//4j/2P/n/7//xP/Y/+wAAP/YAAAAAAAAAAAAAAAAAAD/xAAAAAD/7AAA/9gAAP/dAAD/2P/JAAAAAP+m/93/l//sAAAAAP/2//b/8f/s//b/uv/TAAD/9gAAAAAAAP+///H/nP/E/5z/3f/i/8T/zv/d//H/8f/dAAAAAAAAAAAAAAAAAAD/xAAA/5z/5wAA/93/3f/d/9j/3f/JAAAAAAAA/84AAP/iAAD/9gAA//EAAP/sAAD/9gAAAAD/9gAAAAAAAP/TAAAAAP/YAAD/zv/s/9j/zv/s//YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/7AAA/+wAAP/YAAD/2AAAAAAAAP+S/8T/fv/dAAAAAP/s/+z/7AAA//b/nP+6AAD/9gAAAAAAAP+S/9j/fv+X/37/sP/Y/5f/nP+1/+z/7P+1AAAAAAAAAAAAAAAAAAD/nAAA/5L/4gAA/7X/xP/J/7r/xP+wAAAAAAAA/9gAAP/2AAAAAAAAAAAAAAAA//YAAP/xAAAAAAAAAAAAAP/nAAAAAP/sAAD/4v/2/+z/7AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/7P/xAAD/8QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//EAAP+1AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/dAAAAAAAAAAAAAAAAAAD/+wAAAAD/7P/sAAD/7AAAAAAAAAAAAAAAAP/2/6YAAAAA/84AAP+6AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP+cAAAAAAAAAAAAAAAAAAAAAAAAAAD/9gAAAAAAAAAAAAAAAP/sAAAAAP/xAAAAAAAA//EAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/9gAAAAAACgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//EAAP+6//H/7AAAAAD/9gAA//YAAAAAAAAAAP/7AAAAAAAAAAD/4v/dAAD/9gAAAAAAAAAAAAAAAAAAAAD/5//s/+L/5//xAAAAAAAA/9gAAAAA/6b/8QAA/5wAAP+SAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/4gAAAAAAAP/EAAD/xAAAAAAAAAAA/+wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/xAAAAAP/xAAAAAAAA//YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/9gAAAAAAAAAAAAAAAP/2AAD/9v/2AAAAAAAA/+wAAAAAAAAAAAAAAAAAAAAAAAD/9gAAAAAAAAAAAAAAAP/sAAAAAP/sAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/8QAAAAAAAAAAAAAAAP/sAAD/9gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/YAAAAAP/xAAAAAP/2AAAAAAAA//b/9gAKAAAAAAAAAAD/8f/xAAAACgAPAAAAAAAAAAAAAAAAAAD/+//7//b/+wAAAAAAAAAAAAAAAAAA/84AAP/s//EAAP/YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/9gAAAAA/5z/8f+I/5wAAP9+AAAAAAAAAAAAAAAAAAAAAP/sAAAAAP/2AAAAAP/x//YAAAAAAAAADwAA/84AAAAAAAAAAP/YAAAAAP/sAAD/5wAAAAD/q/+6AAD/0wAA/+wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/+wAAP+w//b/7AAAAAD/9gAA//YAAAAAAAAAAAAAAAAAAAAAAAD/4v/YAAAAAAAAAAAAAAAAAAAAAAAAAAD/5//n/+L/5//xAAAAAAAA/9gAAAAA/5z/8f+I/5wAAP9+AAAAAAAAAAAAAAAAAAAAAP/sAAAAAP/2AAAAAP/x//YAAAAAAAAAAAAA/84AAAAAAAAAAP/YAAAAAP/sAAD/5wAAAAD/q/+6AAD/xAAA/+wAAP/YAAAAAAAA/6YAAP/Y/93/zv+w/+IAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/+IAAAAAAAAAAAAAAAAAAP/YAAAAAP/2AAD/8f/2/+L/8f/2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/8QAAAB4AAAAeAB4AFP/2AAD/0//2/9MAAAAA//b/8QAAAAAAAAAAAAAAHgAjAAAAHgAjADcAAAAA/9MAAAAAAAAAAAAAAAAAAP/2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/OAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/7oAAP/Y/93/7P+1AAAAAAAAAAAAAAAAAAAAAP/2AAAAAP/7AAAAAAAA//sAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/8f/2//H/8QAAAAAAAP/sAAAAAP/2/6YAAP/E/87/zv+c//EAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/9gAAAAD/9gAAAAD/4v/s/9P/4v/sAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//EAAP+1AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/iAAAAAAAAAAAAAAAAAAAAAAAAAAD/7P/xAAD/8QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/9gAAAAAAAP/YAAAAAP/nAAAAAP/nAAD/7AAA/+f/7P/2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/9gAA//b/7P/sAAD/8QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/9gAA//YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/+wAAP+w//H/7AAAAAD/7AAA/+wAAAAAAAAAAP/2AAAAAAAAAAD/4v/OAAD/7AAAAAAAAAAAAAAAAAAAAAD/4v/n/93/4v/sAAAAAAAA/+IAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/iAAAAAP/iAAAAAAAA/+wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/8QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/+wAAAAA/8T/8QAA/84AAP+6AAAACgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/8QAAAAAAAP/dAAD/3QAAAAAAAP+mAAD/sAAAAAAAAAAAAAAAAAAAAAD/9gAAAAAAAAAAAAAAAP/xAAAAAP/xAAAAAAAA//EAAAAAAAAAAAAAAAAAAAAA/90AAAAAAAD/9gAAAAAADwAAAAAAAAAAAAAAAP/2AAAAAP+c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AAsAAgANABEAAwAYABgACAAaABwACQAiACgADAArAC0AEwAwAD0AFgBAAEIAJABEAEcAJwBKAEoAKwBMAE8ALABRAFoAMABjAGMAOgBoAHEAOwBzAHUARQABAAgAAQAAAAEAAQABAAAAAQAAAAoAMAA+AAJERkxUAA5sYXRuABoABAAAAAD//wABAAAABAAAAAD//wABAAAAAXNzMDEACAAAAAEAAAACAAYADgAGAAAAAQAQAAEAAAABACgAAQAIAAEADgABAAEAeAABAAQAAQB4AAEAAAABAAAAAQABAAb/iQABAAEAeAABAAH//wAKAfQAAAEsAAAA/ABdAZoARQK8AC0CeAA9AzgANwK4ADEA5gBFAa4ARwGuADwBrgBMAmwAQADmADYBmABCAOYAUgH0//oCxgBBAU8AHgJOACwCYgA3ApgALwJdADwCggBAAksAQAJ2ADcCggBCAPAAVwDwADsCbAA8AmwATwJsAFkCFgAlA9QANQMWADgC0gBoAuIASQMOAGgCngBoApAAaAMQAEkC+ABoARIAbwIlACoCywBoAmsAaANkAGgDFgBoA1IASQKcAGgDUgBJAtMAaAKAAEECiAAyAvgAXQLuADgETgA8AtIASQLMADYCsABHAa4AYgH0AAkBrgA3Alj/6AI+ADMClABdAjsAOgKUADwCSAA6AWoALQKUADwCZQBdAPkAXgD5//sCMABdAPkAZAO3AF0CZQBdAoAAOgKUAF0ClAA8AZAAXQHxADMBkAAqAmUAUwJGADUDXQA6AjoAQwJMADQCKgA9AeAANwEeAHkB4AA1APwAXQJFAD4ChABCAq4ANQM+ADUBhgA6AgMANwGgACIBwgBKAOYAUgGGAC8CAwBDAhYANAIQAEIDggBCAOYATQDmADsA5gA2AZoATQGaADsBmgA2AdYAbwKoAFIBNwA3ATcAQwLQADcCsgAWArYAMg==); font-weight:300; font-style:normal; } \ No newline at end of file diff --git a/docs/static/fonts/332720/78E7259F6E64A8FDC.eot b/docs/static/fonts/332720/78E7259F6E64A8FDC.eot deleted file mode 100644 index ba441e1d8c..0000000000 Binary files a/docs/static/fonts/332720/78E7259F6E64A8FDC.eot and /dev/null differ diff --git a/docs/static/fonts/332720/7A39E6B5C7FDD35E3.css b/docs/static/fonts/332720/7A39E6B5C7FDD35E3.css deleted file mode 100644 index e23ea0ab49..0000000000 --- a/docs/static/fonts/332720/7A39E6B5C7FDD35E3.css +++ /dev/null @@ -1,19 +0,0 @@ - -/* - Copyright (C) 2011-2015 Hoefler & Co. - This software is the property of Hoefler & Co. (H&Co). - Your right to access and use this software is subject to the - applicable License Agreement, or Terms of Service, that exists - between you and H&Co. If no such agreement exists, you may not - access or use this software for any purpose. - This software may only be hosted at the locations specified in - the applicable License Agreement or Terms of Service, and only - for the purposes expressly set forth therein. You may not copy, - modify, convert, create derivative works from or distribute this - software in any way, or make it accessible to any third party, - without first obtaining the written permission of H&Co. - For more information, please visit us at http://typography.com. - 171247-88474-20150623 -*/ - -@font-face { font-family:"Gotham Rounded A"; src: url('http://nuclide.io/static/fonts/332720/B3C56516C7577235B.eot'); src: url('http://nuclide.io/static/fonts/332720/B3C56516C7577235B.eot?#hfj') format('embedded-opentype'); font-style:normal; font-weight:300; } @font-face { font-family:"Gotham Rounded 3r"; src: url('http://nuclide.io/static/fonts/332720/B3C56516C7577235B.eot'); src: url('http://nuclide.io/static/fonts/332720/B3C56516C7577235B.eot?#hfj') format('embedded-opentype'); font-style:normal; font-weight:300; } \ No newline at end of file diff --git a/docs/static/fonts/332720/7C6BEE7159DD678EF.css b/docs/static/fonts/332720/7C6BEE7159DD678EF.css deleted file mode 100644 index f2de0ea247..0000000000 --- a/docs/static/fonts/332720/7C6BEE7159DD678EF.css +++ /dev/null @@ -1,19 +0,0 @@ - -/* - Copyright (C) 2011-2015 Hoefler & Co. - This software is the property of Hoefler & Co. (H&Co). - Your right to access and use this software is subject to the - applicable License Agreement, or Terms of Service, that exists - between you and H&Co. If no such agreement exists, you may not - access or use this software for any purpose. - This software may only be hosted at the locations specified in - the applicable License Agreement or Terms of Service, and only - for the purposes expressly set forth therein. You may not copy, - modify, convert, create derivative works from or distribute this - software in any way, or make it accessible to any third party, - without first obtaining the written permission of H&Co. - For more information, please visit us at http://typography.com. - 171247-88474-20150623 -*/ - -@font-face{ font-family: "Gotham Rounded A"; src: url(data:application/x-font-woff;base64,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); font-weight:300; font-style:normal; } \ No newline at end of file diff --git a/docs/static/fonts/332720/888DDF1B4B9C1A5D5.css b/docs/static/fonts/332720/888DDF1B4B9C1A5D5.css deleted file mode 100644 index 93e7cb801c..0000000000 --- a/docs/static/fonts/332720/888DDF1B4B9C1A5D5.css +++ /dev/null @@ -1,19 +0,0 @@ - -/* - Copyright (C) 2011-2015 Hoefler & Co. - This software is the property of Hoefler & Co. (H&Co). - Your right to access and use this software is subject to the - applicable License Agreement, or Terms of Service, that exists - between you and H&Co. If no such agreement exists, you may not - access or use this software for any purpose. - This software may only be hosted at the locations specified in - the applicable License Agreement or Terms of Service, and only - for the purposes expressly set forth therein. You may not copy, - modify, convert, create derivative works from or distribute this - software in any way, or make it accessible to any third party, - without first obtaining the written permission of H&Co. - For more information, please visit us at http://typography.com. - 171247-88474-20150623 -*/ - -@font-face{ font-family: "Gotham Rounded A"; src: url(data:font/opentype;base64,MgA/Al0APwA9ACoCOgBdA1MAZQIzAD8BXQA/AToAPwI8AD8CSQA/AmgAFgNvABIBaAA/AmgAPwI1AD8DQgA/AjcAdgJAAD8CPABdAjcAYgIsAE4CHgBPAUEAPwI9AHgCXQA/AAAALAEAAD8BCgA/PwEAAQAAAAIAAAAEAAEAGgABAAEAAgAAAAAAGAAAAA4AAAABAAALHz8/P35/Pz9/fz8/Pz8/Pz8LHz8/P38/Pz8/Pz8/Pz8/Pz8LHj8/Pz8GfR8/Pz8/Cx8/Pz8/CD8/Pz8/PwY/CD8/Pz8/Px8/Pz9/fz8/Pwg/fT8/Pz9YRjQnAQEEABM/FT8/FBY/Dh8/Pz8/Pz8/Pz8/Pz8/Pz8/FT9YPwc/Yj8/bj8/P3V7Pz8Gbj8/Pz8/Pz8/eT8/Pz8/FWhzPwohFT8/CiAVPz8/CH54P30/Pz90Pz8/P3w/fD97PxU/PwU/CD8/Pz8/Pz8/Pz8/Px4/Pz8/Pz8/PxU/Fz8HfT8fPz8/Pz8/Pz8ePz8/Pz8/Pz8VPxs/CD8/Pz8/Pz8/Pz8/Pz8/Pz8/Px8/Pz8/FXBoBj8/CD8/Pz8/Pz8/Pz8/Pz8/Pz8/PwU/Pwg/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8ePz8/Pz8/Pz8IPz8/Pz8/Pz8/Pz8/Pz8/Pz8/Bz8/FVt3Pwc/cj8/ej8IPz8/Pz8/Hj8/Pz8HPz8/Pz8/eR4/Pz8/Pz8/PwY/Pz8/FXw/ZT8IPz8/Pz8/P3I/ej93P3Z/f3o/BT8/CD8/Pz8/Pz8/Pz9pPz8/Pz8/Pz9jP1Y/YT9sbnlWdT95P24/HmBhYUhNP2o/CD8/Pz8/Pz9wP3c/P3N7fXg/ch9vP3U/Pz8/Pwg/Pz8/fD8VSj8iPwc/fj8/Px8/Pz8/CD8/Pz8/PwU/Pwg/Pz8/Pz8ePz8/Pwd3Pz8/PxUqPwg/P3Q/bD98P30/Pz8/eT9vP28/Pz8/Pz8VFz9iBj8IPz8/Pz8/Pz8/Pz8/Pz8/P3s/Pz8/Pz8/Pz8/Pz8/BT8/Bj8/Pwg/Pz8/Pz8/Pz8/Pz8/Pz9zPz8/Pz8/Pz8/Pz8/Pz8FPz8/PxU/Px56fz97ej9/Pwg/Pz8/Pz91P30/dD8VPz8tPwg/Pz8/Pz8/Pz8/Pz8/P3Q/Pz8FPz8/Pz9yPz8/Pz8/dz8/Pz8/P3o/Pz8/Pz8IPz8/Pz8/Hz8/Pz8/Pz8/FVk/Bz8/eT8IPz8/Pz8/Hz8/Pz8/Pz8/CD8/Pz8/PwU/Pz8/FT97Bz9yPz95Pwg/Pz8/Pz8ePz8/Pz8/Pz8/Pz8/Bz8IPz8/Pz8/Bj8/Pz8VPwc/cj8/Pz8ffj8/Pwg/Pz8/Pz8FPz8GPz8/Pz8/cj8/Pz8/FTsrHz8/Pz8/Pz8/Pz8/Pz8/Pz8VPxI/Hz8/P3p5f359CD8/Pz8/PwU/PwY/Pz8Ifz8/Pz8/Hz8/Pz8/Pz8/CD8/Pz8/PwY/CD8/Pz8/PxVRPyY/Bj8/Pz8VQT9VPwojFT8GP2I/P1g/Pwg/Pz8/Pz8GPz8/CD8/Pz8/PwY/Pz8IPz8/Pz8/Bj8/Pz8/FT85PwojBD8KIhU/PwojBD8KIhVBPwoiFT9QCiEVPz8KIBU/Pw4ePz8/Pz99P3gHcB54fX14eD99Pwc/FQI/Px8/Pz8/Bj8ePz8/fQV3P3sePz8/Pz8/Pz8VPz8hPz8OHj8/Pz8HPwg/Pz8/Pz8FPD8/Pz8fPz8/f38/P38GEz8efz8/Pwc/CD8/Pz8/PwU8Pz8/H38/Pz8/Pz8/BiE/Fj9aDgg/Pz8/fT8FXz87Pwg/Pz8/Pz9+Pz9/P30/fT8/Pz8FQz8oP0U/KD8IPz8/Pz9+Bj8IP30/Pz8/BUU/KD9FPyk/CD8/Pz8/fT99Pz8/Pz8/Pz8/PwVfPzs/CD8/Pz8/PwY/CD8/Pz98PwU1PyU/NT8mPwg/Pz8/Pz8GPxU/Pz8/Pw4ePz8/Pz8/P3wHQQg/Pz8/HhU/Mz8OPwc/Px58Pz99fT8/Pwc/Px4/P1AkJz8+IQc/Px58Pz99fT8/PxV9Pz8/Pw4IP3A/ZD8/Pz8/Pz9+Pz8/P34/Pz8/Pz8/Vj9TP04eRmVVUAc/CE8/dT93P3M/cj8wPwc/HzlQRigIP1Q/Tj9aPz8/Pz8/Pz8/Pz8/Pz8/Pz8/cT97Pz8/Hj8/Pz8HPwg/Pz9GP0I/OT81Pz8HPx8/Pz8/FT8/PyEOHn0/P319Pz8/BxA/CChfVTI/Qz98Pz8/Pz8/Pz8/Pz8APz84Pz8HUD8ePz8/Pz8/P3wVP18/Dh4NPyg0DD8HPx4PPyk/Cj8NPz8MPwc/Hw8/Lwo/FT8/His/Dj8CPyM/Bz8eIz8QPwM/LD8rPw4/Aj8jPwc/HyM/ED8DPyw/FX8/Pz8OHgM/Px0/Bz8eGj8uICEyJRY/Bz8fFz8zPz8VWj8/Px4/Pz8/Pz8/fAcuCD8/Pz8eDz8oET86Pwc/Hzo/JhE/Dz8IPyU/ST9hBz8/Hnw/P319Pz8/FVk/Pw4IPz8/Pz8/BT8/Pz8/Pz8IPz8/Pz8/fz9/fz9+Pz8/Pz8/BT8/fD8/P3k/CD8/Pz8/Pz9+Pz8/Pz8/Pz8/PwU/Pz8/Pz8/CD8/Pz8/Pz8/Pz8/Pz8/Pz8/PwU/Pz8/Pz8/CD8/Pz8/Px4/Pz9+FT8LPw4ffX9/fQY/CD8/Pz8/PwU/P2w/Pz8efT8/fX0/Pz8HKD8fPz8/PwY/CD8/Pz8/PwU/P3U/Pz8ePz8/Pz8/P30VP08/Dh59f399fT9/PwckPx4/Pz8/P38/fRU/Az8/Dh59f399fT9/Pwc/P1Q/Px59f399fT9/PwckPx4/Pz8/P38/fQc/P1Q/Px4/Pz8/P38/fRU/MT8OHj9/P30HHD8ffX9/fQZYPx9+Pz8/Pz8/PwY+Pz8/ET8ffj8/Pz8/Pz8GET8/P0M/H34/Pz8/Pz8/Bl0/FhY/Dh8tLDUpPE8/Pz8/PwQ/P1Q9FT8/Vh8/P1k/Uj8/Pz8/Wz9VPz8/Pz9NP1M/Zz8/Pz8/CD9nP1I/Pz8/Pz8fP0M/ISM/IQ0/BD8IPzo/Xj90BVA/CHw/Pz8/fj97Pz8/PwVWPz8IPz8/Pz8/Hz8/alJFTUElP0s/ST9AP3o/ez9LP0E/cz90P0g/Pz8/Pwg/KXVEYUE/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8VNj8/Pw0/Dh4LPzE/Mwc/Hig8Pwg/Bz8/Pwc/Hz8/PAM/FT8/Pwg/aT9gPwg/Pz8/Pz99P38/P30/Pz8/Pz8/VT9WP08/IT8rPyhmPz8/Pz8CPx4hPy0/DD8HPx8VPyEnJj8IP0A/Tj9hP1U/aSA/Pwc/H3A/Mj8OPzc/FX8/Pw4eFT9GPjwHPx40TD8GPwY/Pz8HPx8/Pz4VPwQ/Px4oUTg1Bz8ePFI/Pz8/Pz8HPx8/PzgoBBs/Hic/OgU/CD8HPwg5P01IbjNvP1c/OD8HPx4BP0EHPw0/DT8HPwE/Bz8IPz8/Pz8zP0g/Pwc/Hwg/BT8nPxU/Pz8OHgU/OUEoBz8eK0M/Az8HPz8/Bz8fPz82BT8VPz8IP28/YT9RP0U/JT8/Bz8fZz88PwM/Qj8IP0E/Uj9TCD8/Pz8/Pz8/Pz8/Pz8/Pz8/P2I/dT8/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GAEWARQBEgEPAT8APwA/AD8APwB6AHcAdQBzAG8AZABYAE4ASQBFAEAAOQA2ADMAJAAhADgABQBAAHgAAAAYAgQAHAAAAAEAAwA0AgAAAAABABwAAAADAAAAAwAAAABlAHIAYQB3AHQAZgBvAHMALQB0AG4AbwBmAGIAZQB3AC8AbQBvAGMALgB5AGgAcABhAHIAZwBvAHAAeQB0AC4AdwB3AHcALwAvADoAcAB0AHQAaABtAG8AYwAuAHkAaABwAGEAcgBnAG8AcAB5AHQALgB3AHcAdwA5ADEAMgAwADQAMQAtADMAMgA0ADIALQAzADIANgAwADUAMQAwADIALQA0ADcANAA4ADgALQA3ADQAMgAxADcAMQAgAG0AbwBjAC4AeQBoAHAAYQByAGcAbwBwAHkAdAAuAHcAdwB3ACAAdABhACAALgBvAEMAIAAmACAAcgBlAGwAZgBlAG8ASAAgAHQAYwBhAHQAbgBvAGMAIAByAG8AIAAsAGUAcgBhAHcAdABmAG8AcwAtAHQAbgBvAGYAYgBlAHcALwBtAG8AYwAuAHkAaABwAGEAcgBnAG8AcAB5AHQALgB3AHcAdwAvAC8AOgBwAHQAdABoACAAdABpAHMAaQB2ACAAZQBzAGEAZQBsAHAAIAAsAG4AbwBpAHQAYQBtAHIAbwBmAG4AaQAgAGUAcgBvAG0AIAByAG8ARgAgAC4AZQBzAG8AcAByAHUAcAAgAHkAbgBhACAAcgBvAGYAIABlAHIAYQB3AHQAZgBvAHMAIABzAGkAaAB0ACAAZQBzAHUAIAB0AG8AbgAgAHkAYQBtACAAdQBvAHkAIAAsAHMAdABzAGkAeABlACAAdABuAGUAbQBlAGUAcgBnAGEAIABoAGMAdQBzACAAbwBuACAAZgBJACAALgBvAEMAIAAmACAAcgBlAGwAZgBlAG8ASAAgAGQAbgBhACAAdQBvAHkAIABuAGUAZQB3AHQAZQBiACAAcwB0AHMAaQB4AGUAIAB0AGEAaAB0ACAAdABuAGUAbQBlAGUAcgBnAGEAIABlAGMAaQB2AHIAZQBTACAAZgBvACAAcwBtAHIAZQBUACAAZQBoAHQAIABvAHQAIAB0AGMAZQBqAGIAdQBzACAAcwBpACAAZQByAGEAdwB0AGYAbwBzACAAcwBpAGgAdAAgAGUAcwB1ACAAbwB0ACAAdABoAGcAaQByACAAcgB1AG8AWQAgAC4AbgBvAGkAdABhAGMAbwBsACAAeQBuAGEAIABtAG8AcgBmACAAdABpACAAdABzAG8AaAAgAHIAbwAgACwAcgBlAHQAdQBwAG0AbwBjACAAeQBuAGEAIABuAG8AcAB1ACAAdABpACAAbABsAGEAdABzAG4AaQAgAHIAbwAgACwAZQByAGEAdwB0AGYAbwBzACAAcwBpAGgAdAAgAGQAYQBvAGwAbgB3AG8AZAAgAHIAbwAgACwAZQB0AHUAYgBpAHIAdABzAGkAZAAgACwAeQBmAGkAZABvAG0AIAAsAHkAcABvAGMAIAB0AG8AbgAgAHkAYQBtACAAdQBvAFkAIAAuAG8AQwAgACYAIAByAGUAbABmAGUAbwBIACAAZgBvACAAeQB0AHIAZQBwAG8AcgBwACAAZQBoAHQAIABzAGkAIABlAHIAYQB3AHQAZgBvAHMAIABzAGkAaABUAC4AbwBDACAAJgAgAHIAZQBsAGYAZQBvAEgALgBzAG4AbwBpAHQAYwBpAGQAcwBpAHIAdQBqACAAbgBpAGEAdAByAGUAYwAgAG4AaQAgAGQAZQByAGUAdABzAGkAZwBlAHIAIABlAGIAIAB5AGEAbQAgAGgAYwBpAGgAdwAgACwALgBvAEMAIAAmACAAcgBlAGwAZgBlAG8ASAAgAGYAbwAgAGsAcgBhAG0AZQBkAGEAcgB0ACAAYQAgAHMAaQAgAGQAZQBkAG4AdQBvAFIAIABtAGEAaAB0AG8ARwB0AG4AbwBGADEAMAAyAC4AMQAgAG4AbwBpAHMAcgBlAFYAOQAxADIAMAA0ADEALQAzADIANAAyAC0AMwAyADYAMAA1ADEAMAAyAC0ANAA3ADQAOAA4AC0ANwA0ADIAMQA3ADEAcgBhAGwAdQBnAGUAUgBtAG8AYwAuAHkAaABwAGEAcgBnAG8AcAB5AHQAIAB8ACAAbwBDACYASAAgACkAQwAoACAAdABoAGcAaQByAHkAcABvAEMAbQBvAGMALgB5AGgAcABhAHIAZwBvAHAAeQB0AC4AdwB3AHcALwAvADoAcAB0AHQAaAAgAC4AbwBDACAAJgAgAHIAZQBsAGYAZQBvAEgAIAA3ADAAMAAyACAALAA2ADAAMAAyACAAKQBDACgAIAB0AGgAZwBpAHIAeQBwAG8AQwBlcmF3dGZvcy10bm9mYmV3L21vYy55aHBhcmdvcHl0Lnd3dy8vOnB0dGhtb2MueWhwYXJnb3B5dC53d3c5MTIwNDEtMzI0Mi0zMjYwNTEwMi00NzQ4OC03NDIxNzEgbW9jLnlocGFyZ29weXQud3d3IHRhIC5vQyAmIHJlbGZlb0ggdGNhdG5vYyBybyAsZXJhd3Rmb3MtdG5vZmJldy9tb2MueWhwYXJnb3B5dC53d3cvLzpwdHRoIHRpc2l2IGVzYWVscCAsbm9pdGFtcm9mbmkgZXJvbSByb0YgLmVzb3BydXAgeW5hIHJvZiBlcmF3dGZvcyBzaWh0IGVzdSB0b24geWFtIHVveSAsc3RzaXhlIHRuZW1lZXJnYSBoY3VzIG9uIGZJIC5vQyAmIHJlbGZlb0ggZG5hIHVveSBuZWV3dGViIHN0c2l4ZSB0YWh0IHRuZW1lZXJnYSBlY2l2cmVTIGZvIHNtcmVUIGVodCBvdCB0Y2VqYnVzIHNpIGVyYXd0Zm9zIHNpaHQgZXN1IG90IHRoZ2lyIHJ1b1kgLm5vaXRhY29sIHluYSBtb3JmIHRpIHRzb2ggcm8gLHJldHVwbW9jIHluYSBub3B1IHRpIGxsYXRzbmkgcm8gLGVyYXd0Zm9zIHNpaHQgZGFvbG53b2Qgcm8gLGV0dWJpcnRzaWQgLHlmaWRvbSAseXBvYyB0b24geWFtIHVvWSAub0MgJiByZWxmZW9IIGZvIHl0cmVwb3JwIGVodCBzaSBlcmF3dGZvcyBzaWhULm9DICYgcmVsZmVvSC5zbm9pdGNpZHNpcnVqIG5pYXRyZWMgbmkgZGVyZXRzaWdlciBlYiB5YW0gaGNpaHcgLC5vQyAmIHJlbGZlb0ggZm8ga3JhbWVkYXJ0IGEgc2kgZGVkbnVvUiBtYWh0b0d0bm9GMTAyLjEgbm9pc3JlVjkxMjA0MS0zMjQyLTMyNjA1MTAyLTQ3NDg4LTc0MjE3MXJhbHVnZVJtb2MueWhwYXJnb3B5dCB8IG9DJkggKUMoIHRoZ2lyeXBvQ21vYy55aHBhcmdvcHl0Lnd3dy8vOnB0dGggLm9DICYgcmVsZmVvSCA3MDAyICw2MDAyIClDKCB0aGdpcnlwb0M/A0YAEgAJBAEAAwA/A0YAEQAJBAEAAwA/A0YAEAAJBAEAAwA/CVQADgAJBAEAAwBrBSIEDQAJBAEAAwA/CSQADAAJBAEAAwA/CSQACwAJBAEAAwBrBSIECgAJBAEAAwBRBRoACQAJBAEAAwBRBRoACAAJBAEAAwA/BD8ABwAJBAEAAwA/BAgABgAJBAEAAwBtBBoABQAJBAEAAwA/A0YABAAJBAEAAwArBEIAAwAJBAEAAwAdBA4AAgAJBAEAAwA/A0YAAQAJBAEAAwBXAz8AAAAJBAEAAwBAACMAEgAAAAAAAQBAACMAEQAAAAAAAQBAACMAEAAAAAAAAQAtAyoADgAAAAAAAQAKARECDQAAAAAAAQAbAxIADAAAAAAAAQAbAxIACwAAAAAAAQAKARECCgAAAAAAAQA/AA0ACQAAAAAAAQA/AA0ACAAAAAAAAQA/AGEABwAAAAAAAQA/AAQABgAAAAAAAQA/AA0ABQAAAAAAAQBAACMABAAAAAAAAQBqACEAAwAAAAAAAQBjAAcAAgAAAAAAAQBAACMAAQAAAAAAAQAAAEAAAAAAAAAAAQA/ASQAAAABACAAIAA/Aj8BAAAAAAsAAAA/AD8DPwA4PyADEj8kAAAAb0MmSAAAAAAAAAAASgAAUH8AAD8AAAAAAAAAAAAAAAA/ADIAPwEAAD8CPwI/AAAAPwI/AgQABQAsAU0CAgAAABsAAFAAABsAAAAAAAAAAAAAAAAAAAABAD8DAAAAAD8DAAAQPz8DAAABAAAAAAAAAAIACAAAACADPwM4PwAAHwIsPwAAAAAfAiw/AAAAAD8DCwA/PA9fPz8/LkEAAQAAAAEAIAAAAHgQAAAyAD8/dHNvcD8LAAA/AQAABDM1KGVtYW4GAAAAGAEAAABQGwBweGFtbAAAADAfAAA/Bj89eHRtaCQAAAA/AAAAAANhB2FlaGg2AAAAPwAAAD9HFgNkYWVoCAAAACgfAAALAAAAcHNhZzoDAAA8DQAAAj8/cGFtY2AAAAAgAQAASyU/VTIvU08gAAAACB8AAAQASABGRURHbw4AAD8QAABjPz9PIEZGQzAAAwA/AAsAT1RUTw==))); font-weight:300; font-style:normal; } @font-face{ font-family: "Gotham Rounded B"; src: url(data:font/opentype;base64,T1RUTwALAIAAAwAwQ0ZGIE+2i2MAABCYAAAOb0dERUYASAAEAAAfCAAAACBPUy8yVcclSwAAASAAAABgY21hcO62ywIAAA08AAADOmdhc3AAAAALAAAfKAAAAAhoZWFkAxZHvAAAALwAAAA2aGhlYQdhAwAAAAD0AAAAJGhtdHg9xwbVAAAfMAAAAGxtYXhwABtQAAAAARgAAAAGbmFtZSg1MwQAAAGAAAALu3Bvc3T/uAAyAAAQeAAAACAAAQAAAAEAQS6s5cVfDzz1AAsD6AAAAADQLAIfAAAAANAsAh8AAP84A58DIAAAAAgAAgAAAAAAAAABAAADwP8QAAAD1AAAAAADnwABAAAAAAAAAAAAAAAAAAAAGwAAUAAAGwAAAAICTQEsAAUABAK8AooAAACMArwCigAAAd0AMgD6AAAAAAAAAAAAAAAAoAAAf1AAAEoAAAAAAAAAAEgmQ28AAAAk4BIDIP84AMgDwADwAAAACwAAAAAB/gK8ACAAIAABAAAAJAG2AAEAAAAAAAAAQAAAAAEAAAAAAAEAIwBAAAEAAAAAAAIABwBjAAEAAAAAAAMAIQBqAAEAAAAAAAQAIwBAAAEAAAAAAAUADQCLAAEAAAAAAAYABACYAAEAAAAAAAcAYQCcAAEAAAAAAAgADQD9AAEAAAAAAAkADQD9AAEAAAAAAAoCEQEKAAEAAAAAAAsAEgMbAAEAAAAAAAwAEgMbAAEAAAAAAA0CEQEKAAEAAAAAAA4AKgMtAAEAAAAAABAAIwBAAAEAAAAAABEAIwBAAAEAAAAAABIAIwBAAAMAAQQJAAAAgANXAAMAAQQJAAEARgPXAAMAAQQJAAIADgQdAAMAAQQJAAMAQgQrAAMAAQQJAAQARgPXAAMAAQQJAAUAGgRtAAMAAQQJAAYACASHAAMAAQQJAAcAwgSPAAMAAQQJAAgAGgVRAAMAAQQJAAkAGgVRAAMAAQQJAAoEIgVrAAMAAQQJAAsAJAmNAAMAAQQJAAwAJAmNAAMAAQQJAA0EIgVrAAMAAQQJAA4AVAmxAAMAAQQJABAARgPXAAMAAQQJABEARgPXAAMAAQQJABIARgPXQ29weXJpZ2h0IChDKSAyMDA2LCAyMDA3IEhvZWZsZXIgJiBDby4gaHR0cDovL3d3dy50eXBvZ3JhcGh5LmNvbUNvcHlyaWdodCAoQykgSCZDbyB8IHR5cG9ncmFwaHkuY29tUmVndWxhcjE3MTI0Ny04ODQ3NC0yMDE1MDYyMy0yNDIzLTE0MDIxOVZlcnNpb24gMS4yMDFGb250R290aGFtIFJvdW5kZWQgaXMgYSB0cmFkZW1hcmsgb2YgSG9lZmxlciAmIENvLiwgd2hpY2ggbWF5IGJlIHJlZ2lzdGVyZWQgaW4gY2VydGFpbiBqdXJpc2RpY3Rpb25zLkhvZWZsZXIgJiBDby5UaGlzIHNvZnR3YXJlIGlzIHRoZSBwcm9wZXJ0eSBvZiBIb2VmbGVyICYgQ28uIFlvdSBtYXkgbm90IGNvcHksIG1vZGlmeSwgZGlzdHJpYnV0ZSwgb3IgZG93bmxvYWQgdGhpcyBzb2Z0d2FyZSwgb3IgaW5zdGFsbCBpdCB1cG9uIGFueSBjb21wdXRlciwgb3IgaG9zdCBpdCBmcm9tIGFueSBsb2NhdGlvbi4gWW91ciByaWdodCB0byB1c2UgdGhpcyBzb2Z0d2FyZSBpcyBzdWJqZWN0IHRvIHRoZSBUZXJtcyBvZiBTZXJ2aWNlIGFncmVlbWVudCB0aGF0IGV4aXN0cyBiZXR3ZWVuIHlvdSBhbmQgSG9lZmxlciAmIENvLiBJZiBubyBzdWNoIGFncmVlbWVudCBleGlzdHMsIHlvdSBtYXkgbm90IHVzZSB0aGlzIHNvZnR3YXJlIGZvciBhbnkgcHVycG9zZS4gRm9yIG1vcmUgaW5mb3JtYXRpb24sIHBsZWFzZSB2aXNpdCBodHRwOi8vd3d3LnR5cG9ncmFwaHkuY29tL3dlYmZvbnQtc29mdHdhcmUsIG9yIGNvbnRhY3QgSG9lZmxlciAmIENvLiBhdCB3d3cudHlwb2dyYXBoeS5jb20gMTcxMjQ3LTg4NDc0LTIwMTUwNjIzLTI0MjMtMTQwMjE5d3d3LnR5cG9ncmFwaHkuY29taHR0cDovL3d3dy50eXBvZ3JhcGh5LmNvbS93ZWJmb250LXNvZnR3YXJlAEMAbwBwAHkAcgBpAGcAaAB0ACAAKABDACkAIAAyADAAMAA2ACwAIAAyADAAMAA3ACAASABvAGUAZgBsAGUAcgAgACYAIABDAG8ALgAgAGgAdAB0AHAAOgAvAC8AdwB3AHcALgB0AHkAcABvAGcAcgBhAHAAaAB5AC4AYwBvAG0AQwBvAHAAeQByAGkAZwBoAHQAIAAoAEMAKQAgAEgAJgBDAG8AIAB8ACAAdAB5AHAAbwBnAHIAYQBwAGgAeQAuAGMAbwBtAFIAZQBnAHUAbABhAHIAMQA3ADEAMgA0ADcALQA4ADgANAA3ADQALQAyADAAMQA1ADAANgAyADMALQAyADQAMgAzAC0AMQA0ADAAMgAxADkAVgBlAHIAcwBpAG8AbgAgADEALgAyADAAMQBGAG8AbgB0AEcAbwB0AGgAYQBtACAAUgBvAHUAbgBkAGUAZAAgAGkAcwAgAGEAIAB0AHIAYQBkAGUAbQBhAHIAawAgAG8AZgAgAEgAbwBlAGYAbABlAHIAIAAmACAAQwBvAC4ALAAgAHcAaABpAGMAaAAgAG0AYQB5ACAAYgBlACAAcgBlAGcAaQBzAHQAZQByAGUAZAAgAGkAbgAgAGMAZQByAHQAYQBpAG4AIABqAHUAcgBpAHMAZABpAGMAdABpAG8AbgBzAC4ASABvAGUAZgBsAGUAcgAgACYAIABDAG8ALgBUAGgAaQBzACAAcwBvAGYAdAB3AGEAcgBlACAAaQBzACAAdABoAGUAIABwAHIAbwBwAGUAcgB0AHkAIABvAGYAIABIAG8AZQBmAGwAZQByACAAJgAgAEMAbwAuACAAWQBvAHUAIABtAGEAeQAgAG4AbwB0ACAAYwBvAHAAeQAsACAAbQBvAGQAaQBmAHkALAAgAGQAaQBzAHQAcgBpAGIAdQB0AGUALAAgAG8AcgAgAGQAbwB3AG4AbABvAGEAZAAgAHQAaABpAHMAIABzAG8AZgB0AHcAYQByAGUALAAgAG8AcgAgAGkAbgBzAHQAYQBsAGwAIABpAHQAIAB1AHAAbwBuACAAYQBuAHkAIABjAG8AbQBwAHUAdABlAHIALAAgAG8AcgAgAGgAbwBzAHQAIABpAHQAIABmAHIAbwBtACAAYQBuAHkAIABsAG8AYwBhAHQAaQBvAG4ALgAgAFkAbwB1AHIAIAByAGkAZwBoAHQAIAB0AG8AIAB1AHMAZQAgAHQAaABpAHMAIABzAG8AZgB0AHcAYQByAGUAIABpAHMAIABzAHUAYgBqAGUAYwB0ACAAdABvACAAdABoAGUAIABUAGUAcgBtAHMAIABvAGYAIABTAGUAcgB2AGkAYwBlACAAYQBnAHIA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); font-weight:300; font-style:normal; } \ No newline at end of file diff --git a/docs/static/fonts/332720/8E2ED03EAA5ED8BE2.css b/docs/static/fonts/332720/8E2ED03EAA5ED8BE2.css deleted file mode 100644 index 4aeacc5add..0000000000 --- a/docs/static/fonts/332720/8E2ED03EAA5ED8BE2.css +++ /dev/null @@ -1,19 +0,0 @@ - -/* - Copyright (C) 2011-2015 Hoefler & Co. - This software is the property of Hoefler & Co. (H&Co). - Your right to access and use this software is subject to the - applicable License Agreement, or Terms of Service, that exists - between you and H&Co. If no such agreement exists, you may not - access or use this software for any purpose. - This software may only be hosted at the locations specified in - the applicable License Agreement or Terms of Service, and only - for the purposes expressly set forth therein. You may not copy, - modify, convert, create derivative works from or distribute this - software in any way, or make it accessible to any third party, - without first obtaining the written permission of H&Co. - For more information, please visit us at http://typography.com. - 171247-88474-20150623 -*/ - -@font-face{ font-family: "Gotham Rounded A"; src: url(data:font/opentype;base64,T1RUTwANAIAAAwBQQ0ZGIKWnUnEAABFoAAAs60dERUYApgAEAAA+VAAAACBHUE9T5Gif/gAAPnQAAB1aR1NVQunbLV4AAFvQAAAAgE9TLzJVxSTvAAABQAAAAGBjbWFwaLtaTgAADVwAAAPsZ2FzcAAAAAsAAFxQAAAACGhlYWQDcke8AAAA3AAAADZoaGVhB74DwAAAARQAAAAkaG10eAmBHxsAAFxYAAAB5G1heHAAeVAAAAABOAAAAAZuYW1lKDUzBAAAAaAAAAu7cG9zdP+4ADIAABFIAAAAIAABAAAAAQBByTlTkF8PPPUACwPoAAAAANAsAh4AAAAA0CwCHv/o/zgEEwMiAAAACAACAAAAAAAAAAEAAAPA/xAAAARO/+j/6AQTAAEAAAAAAAAAAAAAAAAAAAB5AABQAAB5AAAAAgHwASwABQAEArwCigAAAIwCvAKKAAAB3QAyAPoAAAAAAAAAAAAAAACgAAB/UAAASgAAAAAAAAAASCZDbwAAACLgEgMg/zgAyAPAAPAAAAALAAAAAAH+ArwAIAAgAAIAAAAkAbYAAQAAAAAAAABAAAAAAQAAAAAAAQAjAEAAAQAAAAAAAgAHAGMAAQAAAAAAAwAhAGoAAQAAAAAABAAjAEAAAQAAAAAABQANAIsAAQAAAAAABgAEAJgAAQAAAAAABwBhAJwAAQAAAAAACAANAP0AAQAAAAAACQANAP0AAQAAAAAACgIRAQoAAQAAAAAACwASAxsAAQAAAAAADAASAxsAAQAAAAAADQIRAQoAAQAAAAAADgAqAy0AAQAAAAAAEAAjAEAAAQAAAAAAEQAjAEAAAQAAAAAAEgAjAEAAAwABBAkAAACAA1cAAwABBAkAAQBGA9cAAwABBAkAAgAOBB0AAwABBAkAAwBCBCsAAwABBAkABABGA9cAAwABBAkABQAaBG0AAwABBAkABgAIBIcAAwABBAkABwDCBI8AAwABBAkACAAaBVEAAwABBAkACQAaBVEAAwABBAkACgQiBWsAAwABBAkACwAkCY0AAwABBAkADAAkCY0AAwABBAkADQQiBWsAAwABBAkADgBUCbEAAwABBAkAEABGA9cAAwABBAkAEQBGA9cAAwABBAkAEgBGA9dDb3B5cmlnaHQgKEMpIDIwMDYsIDIwMDcgSG9lZmxlciAmIENvLiBodHRwOi8vd3d3LnR5cG9ncmFwaHkuY29tQ29weXJpZ2h0IChDKSBIJkNvIHwgdHlwb2dyYXBoeS5jb21SZWd1bGFyMTcxMjQ3LTg4NDc0LTIwMTUwNjIzLTI0MjMtMTQwMjE5VmVyc2lvbiAxLjIwMUZvbnRHb3RoYW0gUm91bmRlZCBpcyBhIHRyYWRlbWFyayBvZiBIb2VmbGVyICYgQ28uLCB3aGljaCBtYXkgYmUgcmVnaXN0ZXJlZCBpbiBjZXJ0YWluIGp1cmlzZGljdGlvbnMuSG9lZmxlciAmIENvLlRoaXMgc29mdHdhcmUgaXMgdGhlIHByb3BlcnR5IG9mIEhvZWZsZXIgJiBDby4gWW91IG1heSBub3QgY29weSwgbW9kaWZ5LCBkaXN0cmlidXRlLCBvciBkb3dubG9hZCB0aGlzIHNvZnR3YXJlLCBvciBpbnN0YWxsIGl0IHVwb24gYW55IGNvbXB1dGVyLCBvciBob3N0IGl0IGZyb20gYW55IGxvY2F0aW9uLiBZb3VyIHJpZ2h0IHRvIHVzZSB0aGlzIHNvZnR3YXJlIGlzIHN1YmplY3QgdG8gdGhlIFRlcm1zIG9mIFNlcnZpY2UgYWdyZWVtZW50IHRoYXQgZXhpc3RzIGJldHdlZW4geW91IGFuZCBIb2VmbGVyICYgQ28uIElmIG5vIHN1Y2ggYWdyZWVtZW50IGV4aXN0cywgeW91IG1heSBub3QgdXNlIHRoaXMgc29mdHdhcmUgZm9yIGFueSBwdXJwb3NlLiBGb3IgbW9yZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpc2l0IGh0dHA6Ly93d3cudHlwb2dyYXBoeS5jb20vd2ViZm9udC1zb2Z0d2FyZSwgb3IgY29udGFjdCBIb2VmbGVyICYgQ28uIGF0IHd3dy50eXBvZ3JhcGh5LmNvbSAxNzEyNDctODg0NzQtMjAxNTA2MjMtMjQyMy0xNDAyMTl3d3cudHlwb2dyYXBoeS5jb21odHRwOi8vd3d3LnR5cG9ncmFwaHkuY29tL3dlYmZvbnQtc29mdHdhcmUAQwBvAHAAeQByAGkAZwBoAHQAIAAoAEMAKQAgADIAMAAwADYALAAgADIAMAAwADcAIABIAG8AZQBmAGwAZQByACAAJgAgAEMAbwAuACAAaAB0AHQAcAA6AC8ALwB3AHcAdwAuAHQAeQBwAG8AZwByAGEAcABoAHkALgBjAG8AbQBDAG8AcAB5AHIAaQBnAGgAdAAgACgAQwApACAASAAmAEMAbwAgAHwAIAB0AHkAcABvAGcAcgBhAHAAaAB5AC4AYwBvAG0AUgBlAGcAdQBsAGEAcgAxADcAMQAyADQANwAtADgAOAA0ADcANAAtADIAMAAxADUAMAA2ADIAMwAtADIANAAyADMALQAxADQAMAAyADEAOQBWAGUAcgBzAGkAbwBuACAAMQAuADIAMAAxAEYAbwBuAHQARwBvAHQAaABhAG0AIABSAG8AdQBuAGQAZQBkACAAaQBzACAAYQAgAHQAcgBhAGQAZQBtAGEAcgBrACAAbwBmACAASABvAGUAZgBsAGUAcgAgACYAIABDAG8ALgAsACAAdwBoAGkAYwBoACAAbQBhAHkAIABiAGUAIAByAGUAZwBpAHMAdABlAHIAZQBkACAAaQBuACAAYwBlAHIAdABhAGkAbgAgAGoAdQByAGkAcwBkAGkAYwB0AGkAbwBuAHMALgBIAG8AZQBmAGwAZQByACAAJgAgAEMAbwAuAFQAaABpAHMAIABzAG8AZgB0AHcAYQByAGUAIABpAHMAIAB0AGgAZQAgAHAAcgBvAHAAZQByAHQAeQAgAG8AZgAgAEgAbwBlAGYAbABlAHIAIAAmACAAQwBvAC4AIABZAG8AdQAgAG0AYQB5ACAAbgBvAHQAIABjAG8AcAB5ACwAIABtAG8AZABpAGYAeQAsACAAZABpAHMAdAByAGkAYgB1AHQAZQAsACAAbwByACAAZABvAHcAbgBsAG8AYQBkACAAdABoAGkAcwAgAHMAbwBmAHQAdwBhAHIAZQAsACAAbwByACAAaQBuAHMAdABhAGwAbAAgAGkAdAAgAHUAcABvAG4AIABhAG4AeQAgAGMAbwBtAHAAdQB0AGUAcgAsACAAbwByACAAaABvAHMAdAAgAGkAdAAgAGYAcgBvAG0AIABhAG4AeQAgAGwAbwBjAGEAdABpAG8AbgAuACAAWQBvAHUAcgAgAHIAaQBnAGgAdAAgAHQAbwAgAHUAcwBlACAAdABoAGkAcwAgAHMAbwBmAHQAdwBhAHIAZQAgAGkAcwAgAHMAdQBiAGoAZQBjAHQAIAB0AG8AIAB0AGgAZQAgAFQAZQByAG0AcwAgAG8AZgAgAFMAZQByAHYAaQBjAGUAIABhAGcAcgBlAGUAbQBlAG4AdAAgAHQAaABhAHQAIABlAHgAaQBzAHQAcwAgAGIAZQB0AHcAZQBlAG4AIAB5AG8AdQAgAGEAbgBkACAASABvAGUAZgBsAGUAcgAgACYAIABDAG8ALgAgAEkAZgAgAG4AbwAgAHMAdQBjAGgAIABhAGcAcgBlAGUAbQBlAG4AdAAgAGUAeABpAHMAdABzACwAIAB5AG8AdQAgAG0AYQB5ACAAbgBvAHQAIAB1AHMAZQAgAHQAaABpAHMAIABzAG8AZgB0AHcAYQByAGUAIABmAG8AcgAgAGEAbgB5ACAAcAB1AHIAcABvAHMAZQAuACAARgBvAHIAIABtAG8AcgBlACAAaQBuAGYAbwByAG0AYQB0AGkAbwBuACwAIABwAGwAZQBhAHMAZQAgAHYAaQBzAGkAdAAgAGgAdAB0AHAAOgAvAC8AdwB3AHcALgB0AHkAcABvAGcAcgBhAHAAaAB5AC4AYwBvAG0ALwB3AGUAYgBmAG8AbgB0AC0AcwBvAGYAdAB3AGEAcgBlACwAIABvAHIAIABjAG8AbgB0AGEAYwB0ACAASABvAGUAZgBsAGUAcgAgACYAIABDAG8ALgAgAGEAdAAgAHcAdwB3AC4AdAB5AHAAbwBnAHIAYQBwAGgAeQAuAGMAbwBtACAAMQA3ADEAMgA0ADcALQA4ADgANAA3ADQALQAyADAAMQA1ADAANgAyADMALQAyADQAMgAzAC0AMQA0ADAAMgAxADkAdwB3AHcALgB0AHkAcABvAGcAcgBhAHAAaAB5AC4AYwBvAG0AaAB0AHQAcAA6AC8ALwB3AHcAdwAuAHQAeQBwAG8AZwByAGEAcABoAHkALgBjAG8AbQAvAHcAZQBiAGYAbwBuAHQALQBzAG8AZgB0AHcAYQByAGUAAAAAAwAAAAMAAAAcAAEAAAAAAuYAAwABAAAAHAAEAsoAAABYAEAABQAYAF0AXwB9AKMApQCrAK4AsAC3ALsAxQDPANYA3QDlAO8A9gD9AQcBGwEjAScBMQE3AUgBUQFbAWUBfgH7Af8CGR6FHvMgFCAaIB4gIiAmIDogrCEi4BL//wAAACAAXwBhAKEApQCpAK4AsAC3ALoAvwDHANEA2ADgAOcA8QD4AP8BCgEeASYBKgE2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AAD/9gAAAAAAAAAA/+wAAAAAAAAAAAAAAAD/9v/2AAAAAAAAAAAAAAAAAAAAAP/2AAAAAP/2AAD/9gAA//YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/9v/2//b/9gAAAAAAAP/TAAD/2P/2/8kAAP/T/93/yf+//9MAAAAAAAAAAP/Y/+z/7AAAAAD/2AAA/9gAAAAAAAAAAAAAAAAAAAAAAAD/4v/sAAAAAAAAAAAAAAAA/9gAAAAAAAAAAAAA//YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/2AAAAAP/2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/9v/2AAD/9gAAAAAAAP+w/+wAAAAAAAAAAAAAAAAAAAAA//b/5wAAAAAAAAAAAAAAAP/xAAD/nP/2/5wAAAAA//YAAP/xAAAAAAAAAAAAAAAAAAAAAAAUAAD/9gAAAAAAAAAAAAAAAP/2AAD/8f/xAAAAAAAAAAAAAAAA/+wAAP/s//H/9v/iAAAACgAAAAAAAP/xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/2AAAAAAAAAAAAAAAAAAAAAAAAAAD/+wAAAAD/+wAAAAAAAP/nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/8QAA//EAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/84AAP/2//b/8f/i/+IAAP/YAAD/9v/2AAAAAAAAAAAAAP/iAAAAAP/nAAD/zv/s/+f/7AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/5wAA/+z/xP/OAAD/zgAAAAAAAAAA/9gAAAAA/5z/7P+N/5wAAP9+AAAAAP/2/7AAAP+IAAAAAP/2AAAAAP/7AAD/2P/s//sAAAAAAAAAAAAAAAAAAP/EAAD/2P/Y/6YAAAAAAAD/7AAAAAD/xP/OAAD/xAAAAAAAAP/YAAD/4v/7/8kAAP/Y/93/zv/E/9gAAAAAAAAAAP/Y/+z/7AAAAAD/2AAA/9gAAAAAAAAAAAAAAAAAAAAAAAD/4v/sAAAAAAAAAAAAAAAA/9gAAAAAAAAAAAAA//sAAAAAAAAAAP+6AAAAAAAAAAAAAAAA//sAAP/2//H/9gAAAAAAAAAAAAAAAP/7AAD/nAAA/5wAAAAPAAAACgAAAAAAAAAAAAAAAAAAAAAAAAAUAAAAAAAAAAAADwAAAAUAAAAKAAAACgAAAAAAAAAAAAAAAAAA/8kAAAAA/90AAP+/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/+wAA//YAAP/s//EAAP/nAAAAAAAAAAAAAAAAAAAAAP/2AAAAAP/7AAAAAAAK//sAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACgAAAAAAAAAAAAAAAAAAAAAAAP/xAAAAAP/2//EAAP/i/+f/5//i//YAAAAAAAAAAP/sAAAAAAAAAAAAAAAAAAAAAP/7AAAAAAAAAAAAAAAAAAAAAP/2AAAAAAAAAAAAAAAAAAD/+wAAAAD/8f/2//H/8f/7AAAAAP+m/8n/kv/xAAAAAAAAAAAAAAAA/+z/ef+6AAD/7AAAAAAAAP95/87/nP+D/5z/pv/O/4P/pv+6/9j/2P+cAAAAAAAAAAAAAAAAAAD/jQAA/6b/zgAA/5z/nP+c/5z/nP+SAAAAAP/nAAD/7AAAAAAAAAAAAAD/9gAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/8QAA//EAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//EAAAAAAAAAAAAA//sAAAAAAAAAAP+c/9gAAP/nAAAAAAAA//YAAP/s//b/ugAAAAD/9gAAAAAAAP+6/+z/iP+//4j/2P/n/7//xP/Y/+wAAP/YAAAAAAAAAAAAAAAAAAD/xAAAAAD/7AAA/9gAAP/dAAD/2P/JAAAAAP+m/93/l//sAAAAAP/2//b/8f/s//b/uv/TAAD/9gAAAAAAAP+///H/nP/E/5z/3f/i/8T/zv/d//H/8f/dAAAAAAAAAAAAAAAAAAD/xAAA/5z/5wAA/93/3f/d/9j/3f/JAAAAAAAA/84AAP/iAAD/9gAA//EAAP/sAAD/9gAAAAD/9gAAAAAAAP/TAAAAAP/YAAD/zv/s/9j/zv/s//YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/7AAA/+wAAP/YAAD/2AAAAAAAAP+S/8T/fv/dAAAAAP/s/+z/7AAA//b/nP+6AAD/9gAAAAAAAP+S/9j/fv+X/37/sP/Y/5f/nP+1/+z/7P+1AAAAAAAAAAAAAAAAAAD/nAAA/5L/4gAA/7X/xP/J/7r/xP+wAAAAAAAA/9gAAP/2AAAAAAAAAAAAAAAA//YAAP/xAAAAAAAAAAAAAP/nAAAAAP/sAAD/4v/2/+z/7AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/7P/xAAD/8QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//EAAP+1AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/dAAAAAAAAAAAAAAAAAAD/+wAAAAD/7P/sAAD/7AAAAAAAAAAAAAAAAP/2/6YAAAAA/84AAP+6AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP+cAAAAAAAAAAAAAAAAAAAAAAAAAAD/9gAAAAAAAAAAAAAAAP/sAAAAAP/xAAAAAAAA//EAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/9gAAAAAACgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//EAAP+6//H/7AAAAAD/9gAA//YAAAAAAAAAAP/7AAAAAAAAAAD/4v/dAAD/9gAAAAAAAAAAAAAAAAAAAAD/5//s/+L/5//xAAAAAAAA/9gAAAAA/6b/8QAA/5wAAP+SAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/4gAAAAAAAP/EAAD/xAAAAAAAAAAA/+wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/xAAAAAP/xAAAAAAAA//YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/9gAAAAAAAAAAAAAAAP/2AAD/9v/2AAAAAAAA/+wAAAAAAAAAAAAAAAAAAAAAAAD/9gAAAAAAAAAAAAAAAP/sAAAAAP/sAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/8QAAAAAAAAAAAAAAAP/sAAD/9gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/YAAAAAP/xAAAAAP/2AAAAAAAA//b/9gAKAAAAAAAAAAD/8f/xAAAACgAPAAAAAAAAAAAAAAAAAAD/+//7//b/+wAAAAAAAAAAAAAAAAAA/84AAP/s//EAAP/YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/9gAAAAA/5z/8f+I/5wAAP9+AAAAAAAAAAAAAAAAAAAAAP/sAAAAAP/2AAAAAP/x//YAAAAAAAAADwAA/84AAAAAAAAAAP/YAAAAAP/sAAD/5wAAAAD/q/+6AAD/0wAA/+wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/+wAAP+w//b/7AAAAAD/9gAA//YAAAAAAAAAAAAAAAAAAAAAAAD/4v/YAAAAAAAAAAAAAAAAAAAAAAAAAAD/5//n/+L/5//xAAAAAAAA/9gAAAAA/5z/8f+I/5wAAP9+AAAAAAAAAAAAAAAAAAAAAP/sAAAAAP/2AAAAAP/x//YAAAAAAAAAAAAA/84AAAAAAAAAAP/YAAAAAP/sAAD/5wAAAAD/q/+6AAD/xAAA/+wAAP/YAAAAAAAA/6YAAP/Y/93/zv+w/+IAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/+IAAAAAAAAAAAAAAAAAAP/YAAAAAP/2AAD/8f/2/+L/8f/2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/8QAAAB4AAAAeAB4AFP/2AAD/0//2/9MAAAAA//b/8QAAAAAAAAAAAAAAHgAjAAAAHgAjADcAAAAA/9MAAAAAAAAAAAAAAAAAAP/2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/OAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/7oAAP/Y/93/7P+1AAAAAAAAAAAAAAAAAAAAAP/2AAAAAP/7AAAAAAAA//sAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/8f/2//H/8QAAAAAAAP/sAAAAAP/2/6YAAP/E/87/zv+c//EAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/9gAAAAD/9gAAAAD/4v/s/9P/4v/sAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//EAAP+1AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/iAAAAAAAAAAAAAAAAAAAAAAAAAAD/7P/xAAD/8QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/9gAAAAAAAP/YAAAAAP/nAAAAAP/nAAD/7AAA/+f/7P/2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/9gAA//b/7P/sAAD/8QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/9gAA//YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/+wAAP+w//H/7AAAAAD/7AAA/+wAAAAAAAAAAP/2AAAAAAAAAAD/4v/OAAD/7AAAAAAAAAAAAAAAAAAAAAD/4v/n/93/4v/sAAAAAAAA/+IAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/iAAAAAP/iAAAAAAAA/+wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/8QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/+wAAAAA/8T/8QAA/84AAP+6AAAACgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/8QAAAAAAAP/dAAD/3QAAAAAAAP+mAAD/sAAAAAAAAAAAAAAAAAAAAAD/9gAAAAAAAAAAAAAAAP/xAAAAAP/xAAAAAAAA//EAAAAAAAAAAAAAAAAAAAAA/90AAAAAAAD/9gAAAAAADwAAAAAAAAAAAAAAAP/2AAAAAP+cAAD/nAAAAAAAAAAAAAAAAAAAAAD/7AAAAAAAAAAAAAAAAP/TAAAAAP/YAAAAAAAA/9gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/4gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/5wAAABQAAP/iAAAAAP/nAAD/pv/n/6YAAAAA/+f/9gAAAAAAAAAAAAAAAAAAAAAAFAAjAAAAAAAA/7UAAAAAAAAAAAAAAAAAAP/2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP+1//b/8QAAAAAAAAAAAAAAAAAAAAD/9gAAAAAAAAAAAAD/7P/dAAD/9gAAAAD/9gAAAAD/9gAAAAD/7P/x/+f/8f/2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/nAAA/5z/4gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP+I/9gAAP/iAAAAAAAAAAAAAAAA/+z/vwAAAAAAAAAAAAAAAP+wAAAAAP+6AAAAAP/n/7oAAAAAAAAAAP/OAAAAAAAAAAAAAAAAAAD/qwAAAAD/7AAA/84AAP/OAAD/zv/EAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/YAAAAAP/xAAAAAP/xAAAAAAAA//H/9gAAAAAAAAAAAAAAAAAAAAAAAAAKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/OAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/5wAAAAAAAAAAAAAAAP/iAAD/q//n/6v/8QAA/+f/4v/xAAAAAAAAAAAAAAAAAAAAAAAAAAD/7AAAAAAAAAAAAAAAAP/xAAD/8f/7AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/7AAAAAAAAP/O//b/7P/nAAD/uv/s/7r/9gAA/+z/7P/2AAAAAAAAAAAAAP/2AAAAAAAAAAD/8QAA/8QAAAAAAAD/8f/2//b/9v/7AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/8QAAAAAAAAAAAAAAAP/dAAAAAP/iAAD/4gAA/+L/0//xAAAAAAAAAAAAAAAAAAAAAAAAAAD/7AAAAAAAAAAAAAAAAP/2AAD/9gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/5wAAAAAAAP/O//b/7P/iAAD/q//n/6v/8QAA/+f/4v/xAAAAAAAAAAAAAP/2AAAAAAAAAAD/7AAA/7oAAAAAAAD/8f/2//b/9v/7AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/TAAAAAP/xAAAAAP/xAAAAAAAA//H/8QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/7AAA/+wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAHAG8AGAAAACwAAAAZAAAAIAAjACIAMwA7AAAAAAAAAAAAAAAAADIAAAAqAB8AHwAAAAAAAAAAAAAAAQACAAMABAAFAAYABwAAAAAACAAJAAoAAAAAAAsADAANAA4ADwAQABEAEgATABQAFQAWAB0AGwAAAAAAFwAaAB4AAAAhACQAJQAoAAAAAAApAAAAKAAoACsAGgAAADAAMQA0ADUANgA3ADgAOQA6ABwAAAAAAAAAAAAAAAAAAAAAACYAAAAAAAAAAAAnAC0AIwAjAC4ALwAgAC4ALwAgAAAAIgAmACcAAQAHAHEADQAAAAAAIQAOAAAAFQAYABcAKQAyACAAAAArAAAAAAAAACgAAAAAABQAFAAAAAAAAAAiAAAAAQAAAAIAAAAAAAAAAgAAAAAAAwAAAAAAAAAAAAIAAAACAAAABAAFAAYABwAIAAkACgALAAAAEAASAAAADAAPABMAFgATABkAGgAPAB0AHgAPAA8AHwAfABMAHwAWAB8AJwAqACwALQAuAC8AMAAxAAAAAAARAAAAAAAAAAAAAAAAABsAJgAAAAAAAAAcACMAGAAYACQAJQAVACQAJQAVAAAAFwAbABwAAAAmAAIAEQAHAAcAAAAJAAkAAQALAAsAAgANABEAAwAYABgACAAaABwACQAiACgADAArAC0AEwAwAD0AFgBAAEIAJABEAEcAJwBKAEoAKwBMAE8ALABRAFoAMABjAGMAOgBoAHEAOwBzAHUARQABAAgAAQAAAAEAAQABAAAAAQAAAAoAMAA+AAJERkxUAA5sYXRuABoABAAAAAD//wABAAAABAAAAAD//wABAAAAAXNzMDEACAAAAAEAAAACAAYADgAGAAAAAQAQAAEAAAABACgAAQAIAAEADgABAAEAeAABAAQAAQB4AAEAAAABAAAAAQABAAb/iQABAAEAeAABAAH//wAKAfQAAAEsAAAA/ABdAZoARQK8AC0CeAA9AzgANwK4ADEA5gBFAa4ARwGuADwBrgBMAmwAQADmADYBmABCAOYAUgH0//oCxgBBAU8AHgJOACwCYgA3ApgALwJdADwCggBAAksAQAJ2ADcCggBCAPAAVwDwADsCbAA8AmwATwJsAFkCFgAlA9QANQMWADgC0gBoAuIASQMOAGgCngBoApAAaAMQAEkC+ABoARIAbwIlACoCywBoAmsAaANkAGgDFgBoA1IASQKcAGgDUgBJAtMAaAKAAEECiAAyAvgAXQLuADgETgA8AtIASQLMADYCsABHAa4AYgH0AAkBrgA3Alj/6AI+ADMClABdAjsAOgKUADwCSAA6AWoALQKUADwCZQBdAPkAXgD5//sCMABdAPkAZAO3AF0CZQBdAoAAOgKUAF0ClAA8AZAAXQHxADMBkAAqAmUAUwJGADUDXQA6AjoAQwJMADQCKgA9AeAANwEeAHkB4AA1APwAXQJFAD4ChABCAq4ANQM+ADUBhgA6AgMANwGgACIBwgBKAOYAUgGGAC8CAwBDAhYANAIQAEIDggBCAOYATQDmADsA5gA2AZoATQGaADsBmgA2AdYAbwKoAFIBNwA3ATcAQwLQADcCsgAWArYAMg==); font-weight:300; font-style:normal; } \ No newline at end of file diff --git a/docs/static/fonts/332720/9C4B82DF21AA64A37.css b/docs/static/fonts/332720/9C4B82DF21AA64A37.css deleted file mode 100644 index 96c8c1f725..0000000000 --- a/docs/static/fonts/332720/9C4B82DF21AA64A37.css +++ /dev/null @@ -1,19 +0,0 @@ - -/* - Copyright (C) 2011-2015 Hoefler & Co. - This software is the property of Hoefler & Co. (H&Co). - Your right to access and use this software is subject to the - applicable License Agreement, or Terms of Service, that exists - between you and H&Co. If no such agreement exists, you may not - access or use this software for any purpose. - This software may only be hosted at the locations specified in - the applicable License Agreement or Terms of Service, and only - for the purposes expressly set forth therein. You may not copy, - modify, convert, create derivative works from or distribute this - software in any way, or make it accessible to any third party, - without first obtaining the written permission of H&Co. - For more information, please visit us at http://typography.com. - 171247-88474-20150623 -*/ - -@font-face{ font-family: "Gotham Rounded A"; src: url(data:font/opentype;base64,T1RUTwANAIAAAwBQQ0ZGILkPphQAABIUAAAk2kdERUYAkAAEAAA28AAAACBHUE9TuESiiwAANxAAABwCR1NVQunFLUgAAFMUAAAAgE9TLzJVxiUrAAABQAAAAGBjbWFw0U4uVAAADVwAAASYZ2FzcAAAAAsAAFOUAAAACGhlYWQDcke+AAAA3AAAADZoaGVhB74DqgAAARQAAAAkaG10eNbiGPsAAFOcAAABjG1heHAAY1AAAAABOAAAAAZuYW1lKDUzBAAAAaAAAAu7cG9zdP+4ADIAABH0AAAAIAABAAAAAQBBj0s7+V8PPPUACwPoAAAAANAsAh8AAAAA0CwCH//o/zgEEwMiAAAACAACAAAAAAAAAAEAAAPA/xAAAARO/+j/6AQTAAEAAAAAAAAAAAAAAAAAAABjAABQAABjAAAAAgIsASwABQAEArwCigAAAIwCvAKKAAAB3QAyAPoAAAAAAAAAAAAAAACgAAB/UAAASgAAAAAAAAAASCZDbwAAACPgEgMg/zgAyAPAAPAAAAALAAAAAAH+ArwAIAAgAAIAAAAkAbYAAQAAAAAAAABAAAAAAQAAAAAAAQAjAEAAAQAAAAAAAgAHAGMAAQAAAAAAAwAhAGoAAQAAAAAABAAjAEAAAQAAAAAABQANAIsAAQAAAAAABgAEAJgAAQAAAAAABwBhAJwAAQAAAAAACAANAP0AAQAAAAAACQANAP0AAQAAAAAACgIRAQoAAQAAAAAACwASAxsAAQAAAAAADAASAxsAAQAAAAAADQIRAQoAAQAAAAAADgAqAy0AAQAAAAAAEAAjAEAAAQAAAAAAEQAjAEAAAQAAAAAAEgAjAEAAAwABBAkAAACAA1cAAwABBAkAAQBGA9cAAwABBAkAAgAOBB0AAwABBAkAAwBCBCsAAwABBAkABABGA9cAAwABBAkABQAaBG0AAwABBAkABgAIBIcAAwABBAkABwDCBI8AAwABBAkACAAaBVEAAwABBAkACQAaBVEAAwABBAkACgQiBWsAAwABBAkACwAkCY0AAwABBAkADAAkCY0AAwABBAkADQQiBWsAAwABBAkADgBUCbEAAwABBAkAEABGA9cAAwABBAkAEQBGA9cAAwABBAkAEgBGA9dDb3B5cmlnaHQgKEMpIDIwMDYsIDIwMDcgSG9lZmxlciAmIENvLiBodHRwOi8vd3d3LnR5cG9ncmFwaHkuY29tQ29weXJpZ2h0IChDKSBIJkNvIHwgdHlwb2dyYXBoeS5jb21SZWd1bGFyMTcxMjQ3LTg4NDc0LTIwMTUwNjIzLTI0MjMtMTQwMjE5VmVyc2lvbiAxLjIwMUZvbnRHb3RoYW0gUm91bmRlZCBpcyBhIHRyYWRlbWFyayBvZiBIb2VmbGVyICYgQ28uLCB3aGljaCBtYXkgYmUgcmVnaXN0ZXJlZCBpbiBjZXJ0YWluIGp1cmlzZGljdGlvbnMuSG9lZmxlciAmIENvLlRoaXMgc29mdHdhcmUgaXMgdGhlIHByb3BlcnR5IG9mIEhvZWZsZXIgJiBDby4gWW91IG1heSBub3QgY29weSwgbW9kaWZ5LCBkaXN0cmlidXRlLCBvciBkb3dubG9hZCB0aGlzIHNvZnR3YXJlLCBvciBpbnN0YWxsIGl0IHVwb24gYW55IGNvbXB1dGVyLCBvciBob3N0IGl0IGZyb20gYW55IGxvY2F0aW9uLiBZb3VyIHJpZ2h0IHRvIHVzZSB0aGlzIHNvZnR3YXJlIGlzIHN1YmplY3QgdG8gdGhlIFRlcm1zIG9mIFNlcnZpY2UgYWdyZWVtZW50IHRoYXQgZXhpc3RzIGJldHdlZW4geW91IGFuZCBIb2VmbGVyICYgQ28uIElmIG5vIHN1Y2ggYWdyZWVtZW50IGV4aXN0cywgeW91IG1heSBub3QgdXNlIHRoaXMgc29mdHdhcmUgZm9yIGFueSBwdXJwb3NlLiBGb3IgbW9yZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpc2l0IGh0dHA6Ly93d3cudHlwb2dyYXBoeS5jb20vd2ViZm9udC1zb2Z0d2FyZSwgb3IgY29udGFjdCBIb2VmbGVyICYgQ28uIGF0IHd3dy50eXBvZ3JhcGh5LmNvbSAxNzEyNDctODg0NzQtMjAxNTA2MjMtMjQyMy0xNDAyMTl3d3cudHlwb2dyYXBoeS5jb21odHRwOi8vd3d3LnR5cG9ncmFwaHkuY29tL3dlYmZvbnQtc29mdHdhcmUAQwBvAHAAeQByAGkAZwBoAHQAIAAoAEMAKQAgADIAMAAwADYALAAgADIAMAAwADcAIABIAG8AZQBmAGwAZQByACAAJgAgAEMAbwAuACAAaAB0AHQAcAA6AC8ALwB3AHcAdwAuAHQAeQBwAG8AZwByAGEAcABoAHkALgBjAG8AbQBDAG8AcAB5AHIAaQBnAGgAdAAgACgAQwApACAASAAmAEMAbwAgAHwAIAB0AHkAcABvAGcAcgBhAHAAaAB5AC4AYwBvAG0AUgBlAGcAdQBsAGEAcgAxADcAMQAyADQANwAtADgAOAA0ADcANAAtADIAMAAxADUAMAA2ADIAMwAtADIANAAyADMALQAxADQAMAAyADEAOQBWAGUAcgBzAGkAbwBuACAAMQAuADIAMAAxAEYAbwBuAHQARwBvAHQAaABhAG0AIABSAG8AdQBuAGQAZQBkACAAaQBzACAAYQAgAHQAcgBhAGQAZQBtAGEAcgBrACAAbwBmACAASABvAGUAZgBsAGUAcgAgACYAIABDAG8ALgAsACAAdwBoAGkAYwBoACAAbQBhAHkAIABiAGUAIAByAGUAZwBpAHMAdABlAHIAZQBkACAAaQBuACAAYwBlAHIAdABhAGkAbgAgAGoAdQByAGkAcwBkAGkAYwB0AGkAbwBuAHMALgBIAG8AZQBmAGwAZQByACAAJgAgAEMAbwAuAFQAaABpAHMAIABzAG8AZgB0AHcAYQByAGUAIABpAHMAIAB0AGgAZQAgAHAAcgBvAHAAZQByAHQAeQAgAG8AZgAgAEgAbwBlAGYAbABlAHIAIAAmACAAQwBvAC4AIABZAG8AdQAgAG0AYQB5ACAAbgBvAHQAIABjAG8AcAB5ACwAIABtAG8AZABpAGYAeQAsACAAZABpAHMAdAByAGkAYgB1AHQAZQAsACAAbwByACAAZABvAHcAbgBsAG8AYQBkACAAdABoAGkAcwAgAHMAbwBmAHQAdwBhAHIAZQAsACAAbwByACAAaQBuAHMAdABhAGwAbAAgAGkAdAAgAHUAcABvAG4AIABhAG4AeQAgAGMAbwBtAHAAdQB0AGUAcgAsACAAbwByACAAaABvAHMAdAAgAGkAdAAgAGYAcgBvAG0AIABhAG4AeQAgAGwAbwBjAGEAdABpAG8AbgAuACAAWQBvAHUAcgAgAHIAaQBnAGgAdAAgAHQAbwAgAHUAcwBlACAAdABoAGkAcwAgAHMAbwBmAHQAdwBhAHIAZQAgAGkAcwAgAHMAdQBiAGoAZQBjAHQAIAB0AG8AIAB0AGgAZQAgAFQAZQByAG0AcwAgAG8AZgAgAFMAZQByAHYAaQBjAGUAIABhAGcAcgBlAGUAbQBlAG4AdAAgAHQAaABhAHQAIABlAHgAaQBzAHQAcwAgAGIAZQB0AHcAZQBlAG4AIAB5AG8AdQAgAGEAbgBkACAASABvAGUAZgBsAGUAcgAgACYAIABDAG8ALgAgAEkAZgAgAG4AbwAgAHMAdQBjAGgAIABhAGcAcgBlAGUAbQBlAG4AdAAgAGUAeABpAHMAdABzACwAIAB5AG8AdQAgAG0AYQB5ACAAbgBvAHQAIAB1AHMAZQAgAHQAaABpAHMAIABzAG8AZgB0AHcAYQByAGUAIABmAG8AcgAgAGEAbgB5ACAAcAB1AHIAcABvAHMAZQAuACAARgBvAHIAIABtAG8AcgBlACAAaQBuAGYAbwByAG0AYQB0AGkAbwBuACwAIABwAGwAZQBhAHMAZQAgAHYAaQBzAGkAdAAgAGgAdAB0AHAAOgAvAC8AdwB3AHcALgB0AHkAcABvAGcAcgBhAHAAaAB5AC4AYwBvAG0ALwB3AGUAYgBmAG8AbgB0AC0AcwBvAGYAdAB3AGEAcgBlACwAIABvAHIAIABjAG8AbgB0AGEAYwB0ACAASABvAGUAZgBsAGUAcgAgACYAIABDAG8ALgAgAGEAdAAgAHcAdwB3AC4AdAB5AHAAbwBnAHIAYQBwAGgAeQAuAGMAbwBtACAAMQA3ADEAMgA0ADcALQA4ADgANAA3ADQALQAyADAAMQA1ADAANgAyADMALQAyADQAMgAzAC0AMQA0ADAAMgAxADkAdwB3AHcALgB0AHkAcABvAGcAcgBhAHAAaAB5AC4AYwBvAG0AaAB0AHQAcAA6AC8ALwB3AHcAdwAuAHQAeQBwAG8AZwByAGEAcABoAHkALgBjAG8AbQAvAHcAZQBiAGYAbwBuAHQALQBzAG8AZgB0AHcAYQByAGUAAAAAAwAAAAMAAAAcAAEAAAAAA5IAAwABAAAAHAAEA3YAAACsAIAABgAsACAAIwAvADQANwA/AEQARwBNAF0AXwBjAHEAdAB2AHkAfQCjAKUAqwCuALAAtwC7AMUAxwDWAN0A5QDvAPYA+AD9AQcBDgEQARMBFQEXARkBGwEjAScBKwEtAS8BMQE3AUIBRAFGAUgBUQFUAVYBWAFaAV4BYAFlAWoBbAFuAXABcgF0AXkBewF9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/+cAAAAAAAAAAAAAAAD/8QAA/5z/9v+cAAAAAP/2AAD/8QAAAAAAAAAAAAAAAAAAAAAAFAAA//YAAAAAAAAAAAAAAAD/9gAA//H/8QAAAAAAAAAAAAAAAP/sAAD/7P/x//b/4gAAAAoAAAAAAAD/8QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/9gAAAAAAAAAAAAAAAAAAAAAAAAAA//sAAAAA//sAAAAAAAD/5wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//EAAP/xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/OAAD/9v/2//H/4v/iAAD/2AAA//b/9gAAAAAAAAAAAAD/4gAAAAD/5wAA/87/7P/n/+wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/+cAAP/s/8T/zgAA/84AAAAAAAAAAP/YAAAAAP+c/+z/jf+cAAD/fgAAAAD/9v+wAAD/iAAAAAD/9gAAAAD/+wAA/9j/7P/7AAAAAAAAAAAAAAAAAAD/xAAA/9j/2P+mAAAAAAAA/+wAAAAA/8T/zgAA/8QAAAAAAAD/2AAA/+L/+//JAAD/2P/d/87/xP/YAAAAAAAAAAD/2P/s/+wAAAAA/9gAAP/YAAAAAAAAAAAAAAAAAAAAAAAA/+L/7AAAAAAAAAAAAAAAAP/YAAAAAAAAAAAAAP/7AAAAAAAAAAD/ugAAAAAAAAAAAAAAAP/7AAD/9v/x//YAAAAAAAAAAAAAAAD/+wAA/5wAAP+cAAAADwAAAAoAAAAAAAAAAAAAAAAAAAAAAAAAFAAAAAAAAAAAAA8AAAAFAAAACgAAAAoAAAAAAAAAAAAAAAAAAP/JAAAAAP/dAAD/vwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//sAAP/2AAD/7P/xAAD/5wAAAAAAAAAAAAAAAAAAAAD/9gAAAAD/+wAAAAAACv/7AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAoAAAAAAAAAAAAAAAAAAAAAAAD/8QAAAAD/9v/xAAD/4v/n/+f/4v/2AAAAAAAAAAD/7AAAAAAAAAAAAAAAAAAAAAD/+wAAAAAAAAAAAAAAAAAAAAD/9gAAAAAAAAAAAAAAAAAA//sAAAAA//H/9v/x//H/+wAAAAD/pv/J/5L/8QAAAAAAAAAAAAAAAP/s/3n/ugAA/+wAAAAAAAD/ef/O/5z/g/+c/6b/zv+D/6b/uv/Y/9j/nAAAAAAAAAAAAAAAAAAA/40AAP+m/84AAP+c/5z/nP+c/5z/kgAAAAD/5wAA/+wAAAAAAAAAAAAA//YAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//EAAP/xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/xAAAAAAAAAAAAAP/7AAAAAAAAAAD/nP/YAAD/5wAAAAAAAP/2AAD/7P/2/7oAAAAA//YAAAAAAAD/uv/s/4j/v/+I/9j/5/+//8T/2P/sAAD/2AAAAAAAAAAAAAAAAAAA/8QAAAAA/+wAAP/YAAD/3QAA/9j/yQAAAAD/pv/d/5f/7AAAAAD/9v/2//H/7P/2/7r/0wAA//YAAAAAAAD/v//x/5z/xP+c/93/4v/E/87/3f/x//H/3QAAAAAAAAAAAAAAAAAA/8QAAP+c/+cAAP/d/93/3f/Y/93/yQAAAAAAAP/OAAD/4gAA//YAAP/xAAD/7AAA//YAAAAA//YAAAAAAAD/0wAAAAD/2AAA/87/7P/Y/87/7P/2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/+wAAP/sAAD/2AAA/9gAAAAAAAD/kv/E/37/3QAAAAD/7P/s/+wAAP/2/5z/ugAA//YAAAAAAAD/kv/Y/37/l/9+/7D/2P+X/5z/tf/s/+z/tQAAAAAAAAAAAAAAAAAA/5wAAP+S/+IAAP+1/8T/yf+6/8T/sAAAAAAAAP/YAAD/9gAAAAAAAAAAAAAAAP/2AAD/8QAAAAAAAAAAAAD/5wAAAAD/7AAA/+L/9v/s/+wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/+z/8QAA//EAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/xAAD/tQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/3QAAAAAAAAAAAAAAAAAA//sAAAAA/+z/7AAA/+wAAAAAAAAAAAAAAAD/9v+mAAAAAP/OAAD/ugAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/nAAAAAAAAAAAAAAAAAAAAAAAAAAA//YAAAAAAAAAAAAAAAD/7AAAAAD/8QAAAAAAAP/xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//YAAAAAAAoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/xAAD/uv/x/+wAAAAA//YAAP/2AAAAAAAAAAD/+wAAAAAAAAAA/+L/3QAA//YAAAAAAAAAAAAAAAAAAAAA/+f/7P/i/+f/8QAAAAAAAP/YAAAAAP+m//EAAP+cAAD/kgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/9gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/+IAAAAAAAD/xAAA/8QAAAAAAAAAAP/sAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/8QAAAAD/8QAAAAAAAP/2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//YAAAAAAAAAAAAAAAD/9gAA//b/9gAAAAAAAP/sAAAAAAAAAAAAAAAAAAAAAAAA//YAAAAAAAAAAAAAAAD/7AAAAAD/7AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//EAAAAAAAAAAAAAAAD/7AAA//YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/2AAAAAD/8QAAAAD/9gAAAAAAAP/2//YACgAAAAAAAAAA//H/8QAAAAoADwAAAAAAAAAAAAAAAAAA//v/+//2//sAAAAAAAAAAAAAAAAAAP/OAAD/7P/xAAD/2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/YAAAAAP+c//H/iP+cAAD/fgAAAAAAAAAAAAAAAAAAAAD/7AAAAAD/9gAAAAD/8f/2AAAAAAAAAA8AAP/OAAAAAAAAAAD/2AAAAAD/7AAA/+cAAAAA/6v/ugAA/9MAAP/sAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/sAAD/sP/2/+wAAAAA//YAAP/2AAAAAAAAAAAAAAAAAAAAAAAA/+L/2AAAAAAAAAAAAAAAAAAAAAAAAAAA/+f/5//i/+f/8QAAAAAAAP/YAAAAAP+c//H/iP+cAAD/fgAAAAAAAAAAAAAAAAAAAAD/7AAAAAD/9gAAAAD/8f/2AAAAAAAAAAAAAP/OAAAAAAAAAAD/2AAAAAD/7AAA/+cAAAAA/6v/ugAA/8QAAP/sAAD/2AAAAAAAAP+mAAD/2P/d/87/sP/iAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/iAAAAAAAAAAAAAAAAAAD/2AAAAAD/9gAA//H/9v/i//H/9gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//EAAAAeAAAAHgAeABT/9gAA/9P/9v/TAAAAAP/2//EAAAAAAAAAAAAAAB4AIwAAAB4AIwA3AAAAAP/TAAAAAAAAAAAAAAAAAAD/9gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/zgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP+6AAD/2P/d/+z/tQAAAAAAAAAAAAAAAAAAAAD/9gAAAAD/+wAAAAAAAP/7AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//H/9v/x//EAAAAAAAD/7AAAAAD/9v+mAAD/xP/O/87/nP/xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/9gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//YAAAAA//YAAAAA/+L/7P/T/+L/7AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/xAAD/tQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/4gAAAAAAAAAAAAAAAAAAAAAAAAAA/+z/8QAA//EAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//YAAAAAAAD/2AAAAAD/5wAAAAD/5wAA/+wAAP/n/+z/9gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//YAAP/2/+z/7AAA//EAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//YAAP/2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/sAAD/sP/x/+wAAAAA/+wAAP/sAAAAAAAAAAD/9gAAAAAAAAAA/+L/zgAA/+wAAAAAAAAAAAAAAAAAAAAA/+L/5//d/+L/7AAAAAAAAP/iAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/4gAAAAD/4gAAAAAAAP/sAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//EAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/sAAAAAP/E//EAAP/OAAD/ugAAAAoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/9gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//EAAAAAAAD/3QAA/90AAAAAAAD/pgAA/7AAAAAAAAAAAAAAAAAAAAAA//YAAAAAAAAAAAAAAAD/8QAAAAD/8QAAAAAAAP/xAAAAAAAAAAAAAAAAAAAAAP/dAAAAAAAA//YAAAAAAA8AAAAAAAAAAAAAAAD/9gAAAAD/nAAA/5wAAAAAAAAAAAAAAAAAAAAA/+wAAAAAAAAAAAAAAAD/0wAAAAD/2AAAAAAAAP/YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/+IAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/+cAAAAUAAD/4gAAAAD/5wAA/6b/5/+mAAAAAP/n//YAAAAAAAAAAAAAAAAAAAAAABQAIwAAAAAAAP+1AAAAAAAAAAAAAAAAAAD/9gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/tf/2//EAAAAAAAAAAAAAAAAAAAAA//YAAAAAAAAAAAAA/+z/3QAA//YAAAAA//YAAAAA//YAAAAA/+z/8f/n//H/9gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/5wAAP+c/+IAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/iP/YAAD/4gAAAAAAAAAAAAAAAP/s/78AAAAAAAAAAAAAAAD/sAAAAAD/ugAAAAD/5/+6AAAAAAAAAAD/zgAAAAAAAAAAAAAAAAAA/6sAAAAA/+wAAP/OAAD/zgAA/87/xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/2AAAAAD/8QAAAAD/8QAAAAAAAP/x//YAAAAAAAAAAAAAAAAAAAAAAAAACgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/zgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/+cAAAAAAAAAAAAAAAD/4gAA/6v/5/+r//EAAP/n/+L/8QAAAAAAAAAAAAAAAAAAAAAAAAAA/+wAAAAAAAAAAAAAAAD/8QAA//H/+wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/+wAAAAAAAD/zv/2/+z/5wAA/7r/7P+6//YAAP/s/+z/9gAAAAAAAAAAAAD/9gAAAAAAAAAA//EAAP/EAAAAAAAA//H/9v/2//b/+wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//EAAAAAAAAAAAAAAAD/3QAAAAD/4gAA/+IAAP/i/9P/8QAAAAAAAAAAAAAAAAAAAAAAAAAA/+wAAAAAAAAAAAAAAAD/9gAA//YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/+cAAAAAAAD/zv/2/+z/4gAA/6v/5/+r//EAAP/n/+L/8QAAAAAAAAAAAAD/9gAAAAAAAAAA/+wAAP+6AAAAAAAA//H/9v/2//b/+wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/0wAAAAD/8QAAAAD/8QAAAAAAAP/x//EAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/+wAAP/sAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEABQBbABgAAAAsAAAAGQAAACAAIwAiADMAAAAyAB8AHwAAAAAAAAAAAAEAAgADAAQABgAHAAgACQAKAAAACwAMAA0ADgAPABAAEQASABMAFAAVABYAHQAbAAAAAAAXABoAHgAhACQAJQAoAAAAAAApAAAAKAAoACsAGgAAADQANgA4ADkAHAAAAAAAAAAAAAAAAAAAACYAAAAAAAAAAAAnAC0AIwAjAC4ALwAgAC4ALwAgAAAAIgAmACcAAQAFAF0ADQAAAAAAIQAOAAAAFQAYABcAKQAAACgAFAAUAAAAAAAAACIAAQAAAAIAAAAAAAIAAwAAAAAAAAACAAAAAgAAAAQABQAGAAcACAAJAAoACwAAABAAEgAAAAwADwATABMAGQAaAA8AHQAeAA8ADwAfAB8AEwAfABYAKgAtAC8AMAAAAAAAEQAAAAAAAAAAAAAAGwAmAAAAAAAAABwAIwAYABgAJAAlABUAJAAlABUAAAAXABsAHAAAACYAAgAOAAUABQAAAAcABwABAAkACQACAAsADgADABAAEgAHABcAHwAKACEALgATADEANwAhADoAOgAoADwAPwApAEEARQAtAE0ATQAyAFIAWwAzAF0AXwA9AAEACAABAAAAAQABAAEAAAABAAAACgAwAD4AAkRGTFQADmxhdG4AGgAEAAAAAP//AAEAAAAEAAAAAP//AAEAAAABc3MwMQAIAAAAAQAAAAIABgAOAAYAAAABABAAAQAAAAEAKAABAAgAAQAOAAEAAQBiAAEABAABAGIAAQAAAAEAAAABAAEABv+fAAEAAQBiAAEAAf//AAoB9AAAASwAAAGaAEUCvAAtAzgANwK4ADEA5gBFAa4ARwGuADwBrgBMAmwAQADmADYBmABCAOYAUgH0//oCmAAvAksAQADwAFcA8AA7AmwAPAJsAE8CbABZAhYAJQMWADgC0gBoAuIASQMOAGgCkABoAxAASQIlACoCywBoAmsAaANkAGgDUgBJApwAaANSAEkC0wBoAoAAQQKIADIC+ABdAu4AOAROADwC0gBJAswANgKwAEcBrgBiAfQACQGuADcCWP/oAj4AMwKUAF0COwA6AkgAOgFqAC0ClAA8AmUAXQD5AF4A+f/7AjAAXQD5AGQDtwBdAmUAXQKAADoClABdApQAPAGQACoCRgA1AjoAQwJMADQB4AA3AR4AeQHgADUCRQA+AoQAQgKuADUDPgA1AYYAOgIDADcBoAAiAcIASgDmAFIBhgAvAgMAQwIWADQCEABCA4IAQgDmAE0A5gA7AOYANgGaAE0BmgA7AZoANgHWAG8CqABSATcANwE3AEMC0AA3ArIAFgK2ADI=); font-weight:300; font-style:normal; } @font-face{ font-family: "Gotham Rounded B"; src: url(data:font/opentype;base64,T1RUTwALAIAAAwAwQ0ZGIE+2i2MAABCYAAAOb0dERUYASAAEAAAfCAAAACBPUy8yVcclSwAAASAAAABgY21hcO62ywIAAA08AAADOmdhc3AAAAALAAAfKAAAAAhoZWFkAxZHvAAAALwAAAA2aGhlYQdhAwAAAAD0AAAAJGhtdHg9xwbVAAAfMAAAAGxtYXhwABtQAAAAARgAAAAGbmFtZSg1MwQAAAGAAAALu3Bvc3T/uAAyAAAQeAAAACAAAQAAAAEAQS6s5cVfDzz1AAsD6AAAAADQLAIfAAAAANAsAh8AAP84A58DIAAAAAgAAgAAAAAAAAABAAADwP8QAAAD1AAAAAADnwABAAAAAAAAAAAAAAAAAAAAGwAAUAAAGwAAAAICTQEsAAUABAK8AooAAACMArwCigAAAd0AMgD6AAAAAAAAAAAAAAAAoAAAf1AAAEoAAAAAAAAAAEgmQ28AAAAk4BIDIP84AMgDwADwAAAACwAAAAAB/gK8ACAAIAABAAAAJAG2AAEAAAAAAAAAQAAAAAEAAAAAAAEAIwBAAAEAAAAAAAIABwBjAAEAAAAAAAMAIQBqAAEAAAAAAAQAIwBAAAEAAAAAAAUADQCLAAEAAAAAAAYABACYAAEAAAAAAAcAYQCcAAEAAAAAAAgADQD9AAEAAAAAAAkADQD9AAEAAAAAAAoCEQEKAAEAAAAAAAsAEgMbAAEAAAAAAAwAEgMbAAEAAAAAAA0CEQEKAAEAAAAAAA4AKgMtAAEAAAAAABAAIwBAAAEAAAAAABEAIwBAAAEAAAAAABIAIwBAAAMAAQQJAAAAgANXAAMAAQQJAAEARgPXAAMAAQQJAAIADgQdAAMAAQQJAAMAQgQrAAMAAQQJAAQARgPXAAMAAQQJAAUAGgRtAAMAAQQJAAYACASHAAMAAQQJAAcAwgSPAAMAAQQJAAgAGgVRAAMAAQQJAAkAGgVRAAMAAQQJAAoEIgVrAAMAAQQJAAsAJAmNAAMAAQQJAAwAJAmNAAMAAQQJAA0EIgVrAAMAAQQJAA4AVAmxAAMAAQQJABAARgPXAAMAAQQJABEARgPXAAMAAQQJABIARgPXQ29weXJpZ2h0IChDKSAyMDA2LCAyMDA3IEhvZWZsZXIgJiBDby4gaHR0cDovL3d3dy50eXBvZ3JhcGh5LmNvbUNvcHlyaWdodCAoQykgSCZDbyB8IHR5cG9ncmFwaHkuY29tUmVndWxhcjE3MTI0Ny04ODQ3NC0yMDE1MDYyMy0yNDIzLTE0MDIxOVZlcnNpb24gMS4yMDFGb250R290aGFtIFJvdW5kZWQgaXMgYSB0cmFkZW1hcmsgb2YgSG9lZmxlciAmIENvLiwgd2hpY2ggbWF5IGJlIHJlZ2lzdGVyZWQgaW4gY2VydGFpbiBqdXJpc2RpY3Rpb25zLkhvZWZsZXIgJiBDby5UaGlzIHNvZnR3YXJlIGlzIHRoZSBwcm9wZXJ0eSBvZiBIb2VmbGVyICYgQ28uIFlvdSBtYXkgbm90IGNvcHksIG1vZGlmeSwgZGlzdHJpYnV0ZSwgb3IgZG93bmxvYWQgdGhpcyBzb2Z0d2FyZSwgb3IgaW5zdGFsbCBpdCB1cG9uIGFueSBjb21wdXRlciwgb3IgaG9zdCBpdCBmcm9tIGFueSBsb2NhdGlvbi4gWW91ciByaWdodCB0byB1c2UgdGhpcyBzb2Z0d2FyZSBpcyBzdWJqZWN0IHRvIHRoZSBUZXJtcyBvZiBTZXJ2aWNlIGFncmVlbWVudCB0aGF0IGV4aXN0cyBiZXR3ZWVuIHlvdSBhbmQgSG9lZmxlciAmIENvLiBJZiBubyBzdWNoIGFncmVlbWVudCBleGlzdHMsIHlvdSBtYXkgbm90IHVzZSB0aGlzIHNvZnR3YXJlIGZvciBhbnkgcHVycG9zZS4gRm9yIG1vcmUgaW5mb3JtYXRpb24sIHBsZWFzZSB2aXNpdCBodHRwOi8vd3d3LnR5cG9ncmFwaHkuY29tL3dlYmZvbnQtc29mdHdhcmUsIG9yIGNvbnRhY3QgSG9lZmxlciAmIENvLiBhdCB3d3cudHlwb2dyYXBoeS5jb20gMTcxMjQ3LTg4NDc0LTIwMTUwNjIzLTI0MjMtMTQwMjE5d3d3LnR5cG9ncmFwaHkuY29taHR0cDovL3d3dy50eXBvZ3JhcGh5LmNvbS93ZWJmb250LXNvZnR3YXJlAEMAbwBwAHkAcgBpAGcAaAB0ACAAKABDACkAIAAyADAAMAA2ACwAIAAyADAAMAA3ACAASABvAGUAZgBsAGUAcgAgACYAIABDAG8ALgAgAGgAdAB0AHAAOgAvAC8AdwB3AHcALgB0AHkAcABvAGcAcgBhAHAAaAB5AC4AYwBvAG0AQwBvAHAAeQByAGkAZwBoAHQAIAAoAEMAKQAgAEgAJgBDAG8AIAB8ACAAdAB5AHAAbwBnAHIAYQBwAGgAeQAuAGMAbwBtAFIAZQBnAHUAbABhAHIAMQA3ADEAMgA0ADcALQA4ADgANAA3ADQALQAyADAAMQA1ADAANgAyADMALQAyADQAMgAzAC0AMQA0ADAAMgAxADkAVgBlAHIAcwBpAG8AbgAgADEALgAyADAAMQBGAG8AbgB0AEcAbwB0AGgAYQBtACAAUgBvAHUAbgBkAGUAZAAgAGkAcwAgAGEAIAB0AHIAYQBkAGUAbQBhAHIAawAgAG8AZgAgAEgAbwBlAGYAbABlAHIAIAAmACAAQwBvAC4ALAAgAHcAaABpAGMAaAAgAG0AYQB5ACAAYgBlACAAcgBlAGcAaQBzAHQAZQByAGUAZAAgAGkAbgAgAGMAZQByAHQAYQBpAG4AIABqAHUAcgBpAHMAZABpAGMAdABpAG8AbgBzAC4ASABvAGUAZgBsAGUAcgAgACYAIABDAG8ALgBUAGgAaQBzACAAcwBvAGYAdAB3AGEAcgBlACAAaQBzACAAdABoAGUAIABwAHIAbwBwAGUAcgB0AHkAIABvAGYAIABIAG8AZQBmAGwAZQByACAAJgAgAEMAbwAuACAAWQBvAHUAIABtAGEAeQAgAG4AbwB0ACAAYwBvAHAAeQAsACAAbQBvAGQAaQBmAHkALAAgAGQAaQBzAHQAcgBpAGIAdQB0AGUALAAgAG8AcgAgAGQAbwB3AG4AbABvAGEAZAAgAHQAaABpAHMAIABzAG8AZgB0AHcAYQByAGUALAAgAG8AcgAgAGkAbgBzAHQAYQBsAGwAIABpAHQAIAB1AHAAbwBuACAAYQBuAHkAIABjAG8AbQBwAHUAdABlAHIALAAgAG8AcgAgAGgAbwBzAHQAIABpAHQAIABmAHIAbwBtACAAYQBuAHkAIABsAG8AYwBhAHQAaQBvAG4ALgAgAFkAbwB1AHIAIAByAGkAZwBoAHQAIAB0AG8AIAB1AHMAZQAgAHQAaABpAHMAIABzAG8AZgB0AHcAYQByAGUAIABpAHMAIABzAHUAYgBqAGUAYwB0ACAAdABvACAAdABoAGUAIABUAGUAcgBtAHMAIABvAGYAIABTAGUAcgB2AGkAYwBlACAAYQBnAHIA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); font-weight:300; font-style:normal; } \ No newline at end of file diff --git a/docs/static/fonts/332720/A59BE2741B1B5D65A.css b/docs/static/fonts/332720/A59BE2741B1B5D65A.css deleted file mode 100644 index 9d5f7c8977..0000000000 --- a/docs/static/fonts/332720/A59BE2741B1B5D65A.css +++ /dev/null @@ -1,19 +0,0 @@ - -/* - Copyright (C) 2011-2015 Hoefler & Co. - This software is the property of Hoefler & Co. (H&Co). - Your right to access and use this software is subject to the - applicable License Agreement, or Terms of Service, that exists - between you and H&Co. If no such agreement exists, you may not - access or use this software for any purpose. - This software may only be hosted at the locations specified in - the applicable License Agreement or Terms of Service, and only - for the purposes expressly set forth therein. You may not copy, - modify, convert, create derivative works from or distribute this - software in any way, or make it accessible to any third party, - without first obtaining the written permission of H&Co. - For more information, please visit us at http://typography.com. - 171247-88474-20150623 -*/ - - \ No newline at end of file diff --git a/docs/static/fonts/332720/B5A3A718F52798BF7.css b/docs/static/fonts/332720/B5A3A718F52798BF7.css deleted file mode 100644 index 9148477f21..0000000000 --- a/docs/static/fonts/332720/B5A3A718F52798BF7.css +++ /dev/null @@ -1,19 +0,0 @@ - -/* - Copyright (C) 2011-2015 Hoefler & Co. - This software is the property of Hoefler & Co. (H&Co). - Your right to access and use this software is subject to the - applicable License Agreement, or Terms of Service, that exists - between you and H&Co. If no such agreement exists, you may not - access or use this software for any purpose. - This software may only be hosted at the locations specified in - the applicable License Agreement or Terms of Service, and only - for the purposes expressly set forth therein. You may not copy, - modify, convert, create derivative works from or distribute this - software in any way, or make it accessible to any third party, - without first obtaining the written permission of H&Co. - For more information, please visit us at http://typography.com. - 171247-88474-20150623 -*/ - -@font-face{ font-family: "Gotham Rounded A"; src: url(data:application/x-font-woff;base64,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); font-weight:300; font-style:normal; } @font-face{ font-family: "Gotham Rounded B"; src: url(data:application/x-font-woff;base64,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); font-weight:300; font-style:normal; } \ No newline at end of file diff --git a/docs/static/fonts/332720/B65C7771D2CCC2100.css b/docs/static/fonts/332720/B65C7771D2CCC2100.css deleted file mode 100644 index a727dfcc29..0000000000 --- a/docs/static/fonts/332720/B65C7771D2CCC2100.css +++ /dev/null @@ -1,19 +0,0 @@ - -/* - Copyright (C) 2011-2015 Hoefler & Co. - This software is the property of Hoefler & Co. (H&Co). - Your right to access and use this software is subject to the - applicable License Agreement, or Terms of Service, that exists - between you and H&Co. If no such agreement exists, you may not - access or use this software for any purpose. - This software may only be hosted at the locations specified in - the applicable License Agreement or Terms of Service, and only - for the purposes expressly set forth therein. You may not copy, - modify, convert, create derivative works from or distribute this - software in any way, or make it accessible to any third party, - without first obtaining the written permission of H&Co. - For more information, please visit us at http://typography.com. - 171247-88474-20150623 -*/ - -@font-face{ font-family: "Gotham Rounded A"; src: url(data:font/opentype;base64,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AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD8/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAoAAAAAAAAAAAAAAAAAAAAAAAAAPz8AAAAAAAA/PwAAAAA/PwAAAAA/PwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/Pz8AAD8/AAA/PwAAPz8AAAAAPz8AAAAAAAAAAAAAAAAAAD8/AAAAAAAAAAA/PwAAAAA/PwAAAAA/PwAAAAAAAAAAAAAAAD8/AAAAAAAAAAAAAAAAPz8AAD8/Pz8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/Pz8/AAA/PwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPz8/Pz8AAAAAPz8AAAAAPz8AAAAAPz8AAD8/PwAAAAAAAAAAAAA/PwAAAAAAAAAAAAAAAAAAAAA/Pz8/Pz8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPz8AAAAAAAAAAAAAAAAAAD8/AAAAAAAAIwAUAAAAAAAAAAAAAAAAAAAAAAA/PwAAAAA/Pz8/AAA/PwAAAAA/PwAAFAAAAD8/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD8/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPz8AAAAAAAA/PwAAAAA/PwAAAAAAAAAAAAAAAD8/AAAAAAAAAAAAAAAAAAAAAD8/AAA/PwAAAAA/PwAAAAAAAAAAAAAAAA8AAAAAAD8/AAAAAAAAPz8AAAAAAAAAAAAAAAAAAAAAPz8AAAAAAAA/PwAAAAA/PwAAAAAAAAAAAAAAAD8/AAAAAAAAAAAAAAAAAAAAAD8/AAA/PwAAAAAAAD8/AAA/PwAAAAAAAD8/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/PwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAoAAAA/PwAAPz8AAD8/PwAAAAA/PwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPz8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/PwAAAAAAAD8/AAAAAD8/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/PwAAAAAAAD8/Pz8/PwAAAAAAAAAAAAAAAAAAAAA/PwAAPz8/AAAAAAAAAAA/PwAAAAAAAAAAPz8AAD8/AAAAAD8/Pz8/AAA/PwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/PwAAPz8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPz8AAD8/Pz8/AAA/PwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPz8/AAA/PwAAPz8AAAAAPz8AAAAAPz8AAAAAAAA/PwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/PwAAPz8/AAAAAAAAAAAAAAAAAAAAAAAAAAA/PwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/PwAAPz8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/Pz8/Pz8AAAAAPz8AAAAAPz8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD8/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/Pz8/Pz8/AAA/Pz8/AAAAAD8/AAAAAAAAPz8/PwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD8/AAAAAAAAPz8AAAAAPz8AAAAAAAAAAAAAAAAAAAAAPz8/PwAAPz8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/PwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/PwAAAAAAAAAAAAAAAAAAPz8AAAAANwAjAB4AAAAjAB4AAAAAAAAAAAAAAD8/Pz8AAAAAPz8/Pz8AAD8/FAAeAB4AAAAeAAAAPz8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD8/Pz8AAD8/AAAAAD8/AAAAAAAAAAAAAAAAAAA/PwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/Pz8/Pz8/AAA/PwAAAAAAAD8/AAA/PwAAPz8AAD8/Pz8AAAAAPz8AAD8/AAAAAD8/AAAAAAAAAAA/PwAAAAAAAAAAAAA/PwAAAAA/PwAAAAA/PwAAAAAAAAAAAAAAAAAAAAB+PwAAPz8/Pz8AAAAAPz8AAAAAAAA/Pz8/Pz8AAAAAAAAAAAAAAAAAAAAAAAAAAD8/PwAAAAAAAAAAAAAAAAAAAAAAAD8/AAA/PwAAAAA/Pz8/Pz8AAD8/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD8/AAA/PwAAPz8/PwAAAAA/PwAAPz8AAAAAPz8AAAAAAAAAAD8/AAAPAAAAAAAAAD8/AAAAAD8/AAAAAD8/AAAAAAAAAAAAAAAAAAAAAH4/AAA/Pz8/PwAAAAA/PwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD8/AAA/Pz8AAD8/AAAAAAAAAAAAAAAAAAA/Pz8/Pz8/PwAAAAAAAAAAAAAAAAAADwAKAAAAPz8/AAAAAAAAAAAKAD8/Pz8AAAAAAAA/PwAAAAA/PwAAAAA/PwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD8/AAA/PwAAAAAAAAAAAAAAAD8/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/PwAAAAA/PwAAAAAAAAAAAAAAAD8/AAAAAAAAAAAAAAAAAAAAAAAAPz8AAAAAAAA/Pz8/AAA/PwAAAAAAAAAAAAAAAD8/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPz8AAAAAAAA/PwAAAAA/PwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPz8AAAAAAAAAAD8/AAA/PwAAAAAAAD8/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/PwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/PwAAPz8AAD8/Pz8AAAAAPz8AAAAAAAA/Pz8/Pz8AAAAAAAAAAAAAAAAAAAAAPz8AAD8/PwAAAAAAAAAAPz8AAAAAAAAAAD8/AAA/PwAAAAA/Pz8/PwAAPz8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAoAAAAAAD8/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPz8AAAAAAAA/PwAAAAA/PwAAAAAAAAAAAAAAAD8/AAAAAAAAAAAAAAAAAAAAAAAAAAA/PwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/PwAAPz8AAAAAPz8/PwAAAAAAAAAAAAAAAD8/AAA/Pz8AAAAAPz8AAAAAAAAAAAAAAAAAAD8/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD8/AAA/PwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPz8AAD8/PwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/Pz8/PwAAPz8AAAAAPz8AAAAAAAAAAAAAPz8AAD8/AAAAAAAAAAAAAAAAPz8AAD8/AAAAAAAAPz8/Pz8/Pz8/AAA/Pz8/AAA/PwAAAAAAAAAAAAAAAAAAPz8/Pz8/Pz8/Pz8/fj8/P34/Pz8/AAAAAAAAPz8AAD8/Pz8/PwAAPz8/PwAAAAA/P34/Pz8/AAAAAAAAPz8AAD8/AAA/PwAAPz8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/Pz8/Pz8AAD8/AAAAAD8/AAAAAAAAPz8AAAAAPz8AAD8/AAA/PwAAPz8AAD8/AAA/PwAAAAAAAD8/Pz8/Pz8AAD8/Pz8AAD8/AAAAAAAAAAAAAAAAAAA/Pz8/Pz8/Pz8/Pz8/Pz8AAAAAAAA/PwAAPz8/Pz8/Pz8/Pz8AAAAAPz8/Pz8/PwAAAAA/Pz8AAD8/AAA/PwAAPz8AAAAAPz8AAAAAAAAAAAAAAAAAAD8/AAA/Pz8/Pz8/Pz8/Pz8/Pz8AAAAAAAA/PwAAAAA/Pz8/AAA/PwAAAAAAAD8/AAA/Pz8/AAAAAAAAAAA/PwAAAAAAAAAAAAA/PwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/PwAAPz8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAPz8AAAAAAAAAAAAAPz8AAD8/AAAAAD8/Pz8/Pz8/Pz8/PwAAPz8/PwAAPz8AAAAAAAAAAAAAAAAAAD8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/eT8AAAAAAAA/PwAAPz95Pz8AAAAAAAAAAAAAAAA/Pz8/Pz8/AAAAAD8/Pz8AAAAAPz8AAAAAAAAAAAAAAAAAAD8/AAAAAAAAAAAAAAAAAAAAAD8/AAAAAAAAAAAAAAAAAAAAAD8/AAAAAAAAAAA/Pz8/PwAAPz8/PwAAAAA/PwAAAAAAAAAAAAAAAAAAAAAAAAoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPz8KAAAAAAA/PwAAAAA/PwAAAAAAAAAAAAAAAAAAAAA/PwAAPz8/AAA/PwAAPz8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD8/AAA/PwAAAAA/PwAAAAAAAAAAAAAAAAAACgAAAAoAAAAFAAAADwAAAAAAAAAAABQAAAAAAAAAAAAAAAAAAAAAAAAACgAAAA8AAAA/PwAAPz8AAD8/AAAAAAAAAAAAAAAAPz8/PwAAPz8AAAAAAAAAAAAAAAA/PwAAAAAAAAAAPz8AAAAAAAAAAAAAPz8AAAAAAAAAAAAAAAA/Pz8AAAAAAAAAAAAAAAAAAAAAAAA/PwAAPz8AAAAAPz8/PwAAAAAAAAAAPz8/Pz8/AAA/Pz8/AAA/PwAAAAAAAD8/AAA/Pz8AAAAAPz8AAAAAAAA/Pz8/AAA/PwAAAAAAAAAAAAAAAAAAPz8/AAA/PwAAAAA/PwAAAAA/PwAAPz8/PwAAAAB+PwAAPz8/Pz8/AAAAAD8/AAAAAAAAAAA/PwAAPz8/PwAAPz8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPz8/Pz8AAD8/AAAAAD8/AAAAAAAAAAAAAD8/Pz8AAD8/AAA/Pz8/Pz8/PwAAPz8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPz8AAD8/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/PwAAAAAAAD8/AAAAAD8/AAAAAAAAAAAAAAAAAAAAAAAAAAA/PwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/PwAAAAAAAAoAAAA/Pz8/AAA/PwAAAAAAAAAAAAAAAD8/PwAAPz8AAAAAAAAAAAAAAAA/PwAAFAAAAAAAAAAAAAAAAAAAAAAAPz8AAD8/AAAAAD8/Pz8/PwAAPz8AAAAAAAAAAAAAAAA/Pz8/AAAAAAAAAAAAAAAAAAAAAD8/Pz8AAAAAAAA/PwAAPz8/PwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPz8AAAAAPz8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD8/AAAAAAAAAAAAAD8/AAAAAAAAAAAAAAAAPz8/AAAAAAAAAAAAAAAAAAAAAAAAPz8AAD8/AAAAAD8/Pz8AAAAAAAAAAD8/Pz8/Pz8AAD8/Pz8/AAA/PwAAAAAAAD8/Pz8/Pz8/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPz8AAD8/AAA/PwAAAAA/PwAAAAAAAAAAAAAAAAAAAAA/Pz8/AAAAAAAAAAAAAAAAPz8AAAAAAAAAAD8/AAA/PwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/PwAAPz8AAAAAPz8AAAAAAAAAAAAAAAAAAD8/AAA/Pz8/PwAAPz8AAAAAAAA/Pz8/Pz8AAD8/AAAAAAAAAAAAAAAAPz8/Pz8AAD8/AAAAAD8/AAAAAD8/AAA/PwAAAAAAAD8/AAA/Pz8/PwAAPz8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMwA8AD8YPxcAAAQAPxkCAHYAaQBgAF8AWgBXAFUAUAA9ADwAOQA3ADIAMQArACcAIwAaABkAGAAXABYAFQAUABMAEQAQAAsACQAHAAUAHwABABQAEgABAD8/VQA/PzkAPz83AAMA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HmBhYUhNP2o/CD8/Pz8/Pz9wP3c/P3N7fXg/ch9vP3U/Pz8/Pwg/Pz8/fD8VSj8iPwc/fj8/Px8/Pz8/CD8/Pz8/PwU/Pwg/Pz8/Pz8ePz8/Pwd3Pz8/PxUqPwg/P3Q/bD98P30/Pz8/eT9vP28/Pz8/Pz8VFz9iBj8IPz8/Pz8/Pz8/Pz8/Pz8/P3s/Pz8/Pz8/Pz8/Pz8/BT8/Bj8/Pwg/Pz8/Pz8/Pz8/Pz8/Pz9zPz8/Pz8/Pz8/Pz8/Pz8FPz8/PxU/Px56fz97ej9/Pwg/Pz8/Pz91P30/dD8VPz8tPwg/Pz8/Pz8/Pz8/Pz8/P3Q/Pz8FPz8/Pz9yPz8/Pz8/dz8/Pz8/P3o/Pz8/Pz8IPz8/Pz8/Hz8/Pz8/Pz8/FVk/Bz8/eT8IPz8/Pz8/Hz8/Pz8/Pz8/CD8/Pz8/PwU/Pz8/FT97Bz9yPz95Pwg/Pz8/Pz8ePz8/Pz8/Pz8/Pz8/Bz8IPz8/Pz8/Bj8/Pz8VPwc/cj8/Pz8ffj8/Pwg/Pz8/Pz8FPz8GPz8/Pz8/cj8/Pz8/FTsrHz8/Pz8/Pz8/Pz8/Pz8/Pz8VPxI/Hz8/P3p5f359CD8/Pz8/PwU/PwY/Pz8Ifz8/Pz8/Hz8/Pz8/Pz8/CD8/Pz8/PwY/CD8/Pz8/PxVRPyY/Bj8/Pz8VQT9VPwoyFT8GP2I/P1g/Pwg/Pz8/Pz8GPz8/CD8/Pz8/PwY/Pz8IPz8/Pz8/Bj8/Pz8/FT85PwoyBD8KMRU/PwoyBD8KMRVBPwoxFT9QCjAVPz8KLxU/Pz8OHz8/Pz8GPwg/Pz8/Pz8FST8LP0k/Cz8IPz8/Pz8/Bj8ePz8/Pwc/Px4/Pz8/Pz8/PwV2Pz8xPwg/Pz8/Pz8/Pz8/Pz8FMT92Pz8ePz8/Pz8/Pz8VPz9iPwY/Hz8/Pz8/Pz8/Bmc/Hz8/Pz8/Pz8/Bz8/Px4/Pz8/Pz8/PxUpPxM/Dgg/Pz8/Pz8/Pz8/Hj8jPy0/PwY/Hz8/P35+Pz9+BkwIeT94P3g/dD91P3U/Bj8fPz8/fn4/P34GQQgjP2ciJT8WPwg/Aj8/Rz9XPz8/Pz8/Pz8/Pz8/Pz8/Pz8/Rj9kPz8/Pwo/PwY/Px9+Pz8/Pz8/PwY/Pwg/Pz8/Pz8/Pz8/Pz8GPz8ffj8/Pz8/Pz8GPz8IEj9sPzY/BT8/OVxSSV4/Pz8/Pz8efj8/PxUcPyY/DgorFWc/Pz8OCioVP3E/Pw4KLhZ2PwouFnY/Ci4VPz8/Dh4/VD9HBz8eR1RQSks/Tz8HPx8/Pz8/FXg/fz8mPw4KLRZIPwokFTE/Yj8OCi0WSD8KLRU/P2I/DgosFkg/CiwVRD8/Yj8OCiQVMT8OCi0VPz8OCiwVRD8/Pw4fP38/fX1/f30GXj8ffT9/Pz8/Pz8GXj8VPz8/Dh8/fz99fX9/fQY/Px99P38/Pz8/PwY/PxU/Mw4KKRUPPz8IPz8/Pz8/BRU/Pwg/Pz8/Pz8/BD8/Pz8HPx8/P0slCD8/aFFTWj8/Pz8/Pz9+Pz8/Pz8/Pz8/Pz8/Px4YPzM/IAc/CBA/P0krfQg/BQM/Pwh/Pz8/Pz8VPz8/PzkOCisWYD8IPz8/Pz8/BUc/HT8IPz8/Pz8/Pz8/Pz8/BUc/HT8IPz8/Pz8/Pz8/P38/Pz8/Pz8/BUE/Ej9DPxI/CD8/Pz8/Px9/Pz9/FWc/Pz8mDh5QW2JRBz8eT1s/Pz8/Bz8fPz9fURUxPxU/Hz8/Pz8/Pz8/Bj8/Hz8/Pz8/Pz8/Bj8/FQo/Ez8eP0g/PQc/HjxHTjc4P08/Bz8fPz8/PxUvP1Y/dj8OCiAVPz8OHlFaYFYHPx5WWj8/Pz8/Bz8fPz9gUQQ/Hj9HPz0HPx49R0M8PD9DPwc/Hz8/Pz8VMD91Pzo/Dh9yfn14dj8/Pwc/FUE/Hz8/Pz8GSx5nP24/CD8/Pz8/PwU/ZQg/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8FUD8HPz8ePz8/Pz8/Pz8VP0oeNERINgc/HjZFPz8/Pz8/Bz8fPz9JMwQ/Hj88PywHPx4sOz4qKT8/Pwc/Hz8/Pz8VPz9kP1w/DgoqFmA/CD8/Pz8/PwVHPx0/CD8/Pz8/Pz8/Pz8/PwVHPx0/CD8/Pz8/Pz9/Pz8/Pz8/Pz8/PwVBPxI/Qz8SPwg/Pz8/Pz8/Pz8/Pz8VPz0/Jg4fPz8/Pz8/Pz8GcD8fPz8/Pz8/Pz8GcD8VLj8pHlhsXl0HcAg/Pz8/Pz8ePz8/Pwc/Hz8/amUVPz8eP20/Twc/H1BpWEIIP2c/cz90Bz8fWHE/Pwg/Pz8/Pz8IPz8/Pz8/Pz8/Pz8/Pz8/Pz8/fWw/cD9nP2U/bT91P3k/Pz8/BzQ/Hj8/Pz8/Pz8/B3AIPz8/Pz8/FS8/Qj92Pw4ePzY/JAc/HyU0OyQIP1A/ZT9rPz8/Pz8/Pz8/Pz8/Pz8/Pz8/dD94Pz8/Hj8/Pz8HPx8/P00+CD9ee21vbD8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/FSo/Px5SPys/Iz9LPwc/Hks/KT8iP1E/Uj8rPyM/Sz8HPx9LPyk/Ij9RPwQ/Hl8/Nz8yP1k/Bz8eWT85PzQ/Xz9fPzc/Mj9ZPwc/H1k/OT80P18/FX8yP2o/DgZWPx9/Pz8/Pz8/PwdWPx4/Pz8/Pz8/fQYjVj8fPz8/f34/P38GVj8pVj8fPz8/f38/P38FP0Q/Pz8/CD8/Pz8/P30/P38/fT8/Pz8/PwU/Pz8/Pz8/Pwg/Pz8/Pz8/fj8/Pz8/Pz8/Pz8FPz8/Pz9FPx9/Pz8/Pz8/PwZWPxU/PwQ/Dgg/Pz8/Pz8FeT0GPz8fPz8/fn4/P34HSQo/CEA/S3RhYWZmdlc/Tj8pP1E/Xwg/Pz8/Pz8/Pz8/Pz8/Pz8/Pz9dP2k/Pz8/Pz8/Pz8/Pz8/Bgs/Pz8ffj8/Pz8/Pz8GPz8/Pz8/H34/Pz8/Pz8/BnY/Hj8/Pz8VPz8OCD8/VD89BT8/OT8/Hgg/Pw4/Bz8VPz8NPwhnPyc/Bj8/Bz8fIz8QPwY/Jj8FP3xHfgg/Pz8/P34/ez9/Pz8FPz8IP1Q/Yz9pPz8/Pz8/Pz8/Pz8/Pz8/Pz8/bj9xPz8/BUQ/CD9/P38/fwg/S25XX18/Pz8/Pz8/fz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/BT8/CD8/Pz8/Pz8/fj95PxU/bz9oDgopFQI/Px8/Pz8/Bj8ePz8/fQV3P3sePz8/Pz8/Pz8VPz8hPwA/Dgg/PT9rPz8HPx4/P3Qkez8/Pz8/Pz8HPwg/Pz8/PT8/Pz8/fz8/Pz8/Pz9lJT9leyg/B0AIMj9nYnhMdT9qPzI/B0AIKD9lP2UlPz8/Pz8/P38/Pz8/PxVdPxw/Dh5/Pz9/fz8/PwcOPx4/Pz8/Pz8/fxUCPw0/Pw4IaT0/Sz8kPwc8Hj1aPz8/Pz8/Pz97JFp0PQc8CCQ/S2tpPT8/Pz8/Pz8/Pz8/Pz8/JT8/Pwc/CD8/Pz8/P0g/Zj8/Bz8IPz8/ez8lPz8/Pz8/Pz8/Pz8/PxUfPyo/HD8OHj8/Pz8HPwg/Pz8/Pz8FPD8/Pz8fPz8/f38/P38GEz8efz8/Pwc/CD8/Pz8/PwU8Pz8/H38/Pz8/Pz8/BiE/Fj9NDgg/Pz8/Pz8/Pz8/Pz9+Pz8/P34/Pz8/Pz8/ez95P2w/U2ZpP2oFPz9rP3g/CD8/Pz8/P30/Pz8/fD98Pz8/PwVMP2A/Tj9GPwg/Pz8/P34/fT8/Pz8/Pz8/Pz8FPz9jPwg/Pz8/PxU3Py8/bw4IPz8/Pz8/BXU/ST9qP0A/CD8/Pz8/P34/Pz8/fj8/Pz8/PwVmPzs/ZD86Pwg/Pz8/Pz8/fz8/Pz8/Pz8/Pz8Faj9BP3U/SD8IPz8/Pz8/Pz8/Pz8/Pz8/Pz8/BXE/Qz9vP0I/CD8/Pz8/Px4/Pz9/FT9dDgg/Pz8/fT8FXz87Pwg/Pz8/Pz9+Pz9/P30/fT8/Pz8FQz8oP0U/KD8IPz8/Pz9+Bj8IP30/Pz8/BUU/KD9FPyk/CD8/Pz8/fT99Pz8/Pz8/Pz8/PwVfPzs/CD8/Pz8/PwY/CD8/Pz98PwU1PyU/NT8mPwg/Pz8/Pz8GPxU/Pz8/Pw4IPz8/Pz8/Bj8IPz8/P34/BWA/YT8IPz8/Pz8/fT8/Pz98P3w/Pz8/BUs/Tj9NP1E/CD8/Pz8/fj99Pz8/Pz8/Pz8/PwViP2I/FT8/aQ4ePz8/Pz8/P3wHQQg/Pz8/HhU/Mz8OPwc/Px58Pz99fT8/Pwc/Px4/P1AkJz8+IQc/Px58Pz99fT8/PxV9Pz8/Pw4eP2A/KgY/Px8/Pz9/fz8/fwdUIj8efT8/fX0/Pz8GIj80Px9/Pz8/Pz8/Pwc0Pz8fPz9gUAg/aD97Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8VPz8/bD8OCD9wP2Q/Pz8/Pz8/fj8/Pz9+Pz8/Pz8/P1Y/Uz9OHkZlVVAHPwhPP3U/dz9zP3I/MD8HPx85UEYoCD9UP04/Wj8/Pz8/Pz8/Pz8/Pz8/Pz8/P3E/ez8/Px4/Pz8/Bz8IPz8/Rj9CPzk/NT8/Bz8fPz8/PxU/Pz8LPw4efT8/fX0/Pz8HED8IKF9VMj9DP3w/Pz8/Pz8/Pz8/PwA/Pzg/PwdQPx4/Pz8/Pz8/fBU/bD8OCicVPz8/Px4/Pz8/Pz8/fAc/Pwg/Pz8/Hg8/KBE/Oj8HPx86PyYRPw8/CD8lP0k/YQcyHn0/P319Pz8/FX0/Pz8OCiYVWj8/Px58Pz99fT8/Pwc/CEhfUEo/Jh4PPxE/Oj8HPx86PxE/Dz8IP1E/Sz8HPz8ePz8/Pz8/P3wVHz8/Dh4NPyg0DD8HPx4PPyk/Cj8NPz8MPwc/Hw8/Lwo/FT8/His/Dj8CPyM/Bz8eIz8QPwM/LD8rPw4/Aj8jPwc/HyM/ED8DPyw/FX8/Pz8OHn0/P319Pz8/Bz8IT2lcUj8uHhU/QA4/Bz8/Hj8/Pz8/Pz98Bz8/HiJGPz8/Pz8/Bz8/Hj8/Pz8/Pz98FT8/Dh59Pz99fT8/Pwc/CFZqWV0/MD8yP1Q/b1JqVlQ/Kx4NP0AUPwc/Px4/Pz8/Pz8/fAc/Px4CP0s/Pz8/PwY/Bz8/Hj8/Pz8/Pz98Bz8/HiFKPz8/Pz8/Bz8/Hj8/Pz8/Pz98FT8/Pw4efT8/fX0/Pz8HRD8ePz8/Pz8/P3wVPwM/Dh59Pz99fT8/PwU/Pz8/Pwg/Pz8/Pz8/fj8/Pz8/Pz8/Pz8FUj9PPz8/XD8IPz8/Pz8/Pz8/Pz8/Pz8/Pz8/BT8/WD8RPxA/Px4/Pz8/Pz8/fBU/Uw4IPz8/Pz8/Pz8/P38/fz8/Pz9/Pz8/Pz8/Hmd0clsHPz8efT8/fX0/Pz8HPz8fPz8/FT8/VQooFTA/Az8OHn0/P319Pz8/B2g/Hj8/Pz8/Pz98FSw/PwooFTA/Az8OHn0/P319Pz8/Bz8/CE9pXFI/Lh4VP0AOPwc/Px4/Pz8/Pz8/fAc/Px4iRj8/Pz8/Pwc/Px4/Pz8/Pz8/fBU/Pw4eIT0iCD8HPx4KPz8/Pz8/Cz8HPx8HPy8iFT8/Pwg/cz9dPz8/Pz8/Pz8/f38/fj8/Pz8/Pz9RP0g/RB4JP0g4Fz8HQQg/tz8/Hg8/LQ4/Jj8HPx8nPywOPw8/CD8lP0Y/YQc6Hn0/P319Pz8/By4/CD8/Pz8/Pz8/PxU2Pz8/DgY/Hz8/P35/Pz9/B1RZCFE/XXtubnFxfWc/Xj9yP3g/ej8/Pz8/Pz8/Pz8/Pz8/Pz8/Px4/PwY/Mz8ffj8/Pz8/Pz8HMz9QPx4/Pz8/Pz8/fRU/Dz8/Pw4IPz8/Px4aPyAIPzM/Bz8fKD8KPyMePyM/Cj8wJj8/Pz8/BiQ/CBM/PzA/Jz9CbVhjYj8/Pz8/Pz9+Pz8/Pz8/Pz8/PxVkPz8IJD8sPz8JPz8/BT8/FT8/Aj9rDgonFVo/Pz8ePz8/Pz8/P3wHLgg/Pz8/Hg8/KBE/Oj8HPx86PyYRPw8/CD8lP0k/YQc/Px58Pz99fT8/PxVZPz8/Dh4nPw4/BT8jPwc/HyM/ED8GPyY/CD8zP1E/XT8/Pz8/Pz8/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YUE/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8VNj8/PwA/DgogFQ8/awg/Pz8/fz8FFT8/CH4/Pz8/fD8EP1Q+Kj8HPx85Rj8/CD8/Pz8/Pz8/Pz8/Pz8/fj8/Pz8/Pz9MVl5HPyYeGD82Pwc/CBA/Pz8/CD8FAz8/CD8/Pz8/PxVHPz8/OQ4IPz8/Pz8/BWw/ND8IP34/Pz8/Bz8IPz8/Pz8/BWw/ND8IPz8/Pz8/Pz8/P34/Pz8/Pz8/BVw/Gz9ePxs/CD8/Pz8/Px9+Pz9+FT8/Az8/DgolBHU/CiUVSz8/Dgg/Pz8/Pz8FbD80Pwg/Pz8/Pz8HPwg/Pz8/P34FbD80Pwg/Pz8/Pz8/fj8/Pz8/Pz8/Pz8FXD8bP14/Gz8IPz8/Pz8/Hz8/Pz8VPz8/Pw4KJBU/P28KIBV1Pww/DgogBD0/CiAVdT8MPw4eCz8xPzMHPx4oPD8IPwc/Pz8HPx8/PzwDPxU/Pz8IP2k/YD8IPz8/Pz8/fT9/Pz99Pz8/Pz8/P1U/Vj9PPyE/Kz8oZj8/Pz8/Aj8eIT8tPww/Bz8fFT8hJyY/CD9AP04/YT9VP2kgPz8HPx9wPzI/Dj83PxV/Pz8/Dh4VP0Y+PAc/HjRMPwY/Bj8/Pwc/Hz8/PhU/BD8/HihRODUHPx48Uj8/Pz8/Pwc/Hz8/OCgEGz8eJz86BT8IPwc/CDk/TUhuM28/Vz84Pwc/HgE/QQc/DT8NPwc/AT8HPwg/Pz8/PzM/SD8/Bz8fCD8FPyc/FT8/Pw4IPz8/Pz8/BT8/Pz8/FT8fPz8/fX0/P30GOj8efT8/Pwg/Pz8/Pz8FFz8/CD8/Pz8/Px4/Pz99FT89P24OHgU/OUEoBz8eK0M/Az8HPz8/Bz8fPz82BT8VPz8IP28/YT9RP0U/JT8/Bz8fZz88PwM/Qj8IP0E/Uj9TCD8/Pz8/Pz8/Pz8/Pz8/Pz8/P2I/dT8/PyI/KT9qPz9HY01KPwY/HhM/Bj8RPwc/Hxg/Px4/FX8/Pz8OCD9eP1Q/Pz8/Pz8/fz9/Pz99Pz8/Pz/GUD9HP0UeAz9APiYHPx8oSD8FPwg/Pz8/Pz8/Pz8/Pz8/fj98PwU/P3oIeD8/fz99Bj8/H30/Pz8/Pz8/BT8/Pz8/CHVee14/Sh4bPyIRPwc/HxU/PyE/FX8/Pz8OBTI/PzI/PxU/PwYHPx4/Pz97CD8/Pz8/PwVxPxY/CD8/Pz8/fx56P38/BmQ/LB9/Pz8/Pz8/Pwc/Kj8ePz8/Pz8/P30VP1E/Pw4IPwE/Wz9HPz8/Pz8/P30/f38/fT8/Pz8/P1Q/SD8zHi1MPC8HPx8pVT8SPwY/Hj8/P34IPz8/Pz8/BT8/ej8/Hz8/P319Pz99BiI/Hn4/Pz8IPz8/Pz8/BT8/fD8IPxk/Bz8UPz8HPx8OPz8NPxV/Pz8/Dgg/Pz8/Pz8FeT8/PwgiCD9PZEE/CDA/UD8/Pz8/Pz8/Pz8/Pz8/Pz9+Pz8/Pz8/PzVQV0s/Cj8eCz8yAT8HPwg/Pz8EPw8/BVY/aj8/Cz8ffT8/Pz8/Pz8GSD8ePz8/fRU/P3EOBT8GPwg/Pz8/Pz8/Pz8/fz9/Pz8/Pz8FXg4/CD8/Pz8/PwY/Hns/Pz8HKD8ePz8/Pz9/P30VP0c/Pz8OHiU/Kz8xNj8HPx43Pyw/JT8lPyo/Nz8HPx82Py0/LyU/FT8/HkY/Oz8DP1U/Bz8eVT89PwU/Rj9GPzs/Az9VPwc/H1U/PT8FP0Y/FX8/Dgg/Pz8/Pz8FCj9YPwg/Pz8/Pz8/fz8/Pz8/Pz8/Pz8FCj9YPwg/Pz8/Pz8ePz8/fxUDPz8IPw4KIBU/Pw4fP34/fHx+fnwGcD8ffD9+Pz8/Pz8GcD8VP2Q/DgokFTE/DgZZPx8/Pz9+fj8/fgdZP1Y/Hn0/P319Pz8/BlY/WT8ffj8/Pz8/Pz8HWT9WPx4/Pz8/Pz8/fRUaPz8/Pw4FPz8IPz8/Pz8/Pz8/Pz8/Pz8/Pz8/BVokWj8IPz8/Pz8/Pz8/Pz8/Pz8/Pz8/BT8wAT8/CH8/Pz8/fz9/Pz8/PwUBPz9NMAg/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8FPz8kCD8/Pz8/Pz8/Pz8/Pz8/Pz8/PwVNPwE/Pwg/Pz8/Pz8/Pz8/fz8VPD9XP04/Dgg/Pz8/Pz8/Pz8/Pz8rKz8VPzY4Pz84Pz8VPysrPwg/Pz8/Pz8/Pz8/Pz8/Pz8/Pz0/JT8oRz8/Rz8/JT8/PT8/Pz8/Pz8VHz9OPw4IPz8/Pz8/KD0/JT9HPz9HPz8lPygoPT8IPz8/Pz8/Pz8/Pz8/Pz8/Pz8rPxU/OD8/OD8/FT82Pys/Pz8/Pz8/Hz8/Pz8VHz8/Tj8OCiEVYT8OCD89YUhHUQVqP2M/CD8DPz8/Bz8fPz9HKxUKP3cIaydaWEk/Bz8eTVs/Pz8/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AG4AIAB5AGEAbQAgAHUAbwB5ACAALABzAHQAcwBpAHgAZQAgAHQAbgBlAG0AZQBlAHIAZwBhACAAaABjAHUAcwAgAG8AbgAgAGYASQAgAC4AbwBDACAAJgAgAHIAZQBsAGYAZQBvAEgAIABkAG4AYQAgAHUAbwB5ACAAbgBlAGUAdwB0AGUAYgAgAHMAdABzAGkAeABlACAAdABhAGgAdAAgAHQAbgBlAG0AZQBlAHIAZwBhACAAZQBjAGkAdgByAGUAUwAgAGYAbwAgAHMAbQByAGUAVAAgAGUAaAB0ACAAbwB0ACAAdABjAGUAagBiAHUAcwAgAHMAaQAgAGUAcgBhAHcAdABmAG8AcwAgAHMAaQBoAHQAIABlAHMAdQAgAG8AdAAgAHQAaABnAGkAcgAgAHIAdQBvAFkAIAAuAG4AbwBpAHQAYQBjAG8AbAAgAHkAbgBhACAAbQBvAHIAZgAgAHQAaQAgAHQAcwBvAGgAIAByAG8AIAAsAHIAZQB0AHUAcABtAG8AYwAgAHkAbgBhACAAbgBvAHAAdQAgAHQAaQAgAGwAbABhAHQAcwBuAGkAIAByAG8AIAAsAGUAcgBhAHcAdABmAG8AcwAgAHMAaQBoAHQAIABkAGEAbwBsAG4AdwBvAGQAIAByAG8AIAAsAGUAdAB1AGIAaQByAHQAcwBpAGQAIAAsAHkAZgBpAGQAbwBtACAALAB5AHAAbwBjACAAdABvAG4AIAB5AGEAbQAgAHUAbwBZACAALgBvAEMAIAAmACAAcgBlAGwAZgBlAG8ASAAgAGYAbwAgAHkAdAByAGUAcABvAHIAcAAgAGUAaAB0ACAAcwBpACAAZQByAGEAdwB0AGYAbwBzACAAcwBpAGgAVAAuAG8AQwAgACYAIAByAGUAbABmAGUAbwBIAC4AcwBuAG8AaQB0AGMAaQBkAHMAaQByAHUAagAgAG4AaQBhAHQAcgBlAGMAIABuAGkAIABkAGUAcgBlAHQAcwBpAGcAZQByACAAZQBiACAAeQBhAG0AIABoAGMAaQBoAHcAIAAsAC4AbwBDACAAJgAgAHIAZQBsAGYAZQBvAEgAIABmAG8AIABrAHIAYQBtAGUAZABhAHIAdAAgAGEAIABzAGkAIABkAGUAZABuAHUAbwBSACAAbQBhAGgAdABvAEcAdABuAG8ARgAxADAAMgAu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)); font-weight:300; font-style:normal; } \ No newline at end of file diff --git a/docs/static/fonts/332720/BC699FA675F9356E3.css b/docs/static/fonts/332720/BC699FA675F9356E3.css deleted file mode 100644 index fc6add2211..0000000000 --- a/docs/static/fonts/332720/BC699FA675F9356E3.css +++ /dev/null @@ -1,19 +0,0 @@ - -/* - Copyright (C) 2011-2015 Hoefler & Co. - This software is the property of Hoefler & Co. (H&Co). - Your right to access and use this software is subject to the - applicable License Agreement, or Terms of Service, that exists - between you and H&Co. If no such agreement exists, you may not - access or use this software for any purpose. - This software may only be hosted at the locations specified in - the applicable License Agreement or Terms of Service, and only - for the purposes expressly set forth therein. You may not copy, - modify, convert, create derivative works from or distribute this - software in any way, or make it accessible to any third party, - without first obtaining the written permission of H&Co. - For more information, please visit us at http://typography.com. - 171247-88474-20150623 -*/ - -@font-face{ font-family: "Gotham Rounded A"; src: url(data:application/x-font-woff;base64,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); font-weight:300; font-style:normal; } @font-face{ font-family: "Gotham Rounded B"; src: url(data:application/x-font-woff;base64,d09GRk9UVE8AABbaAAsAAAAAH5wAAQAAAAAUtAAAAiYAAAaMAAAAAAAAAABDRkYgAAAH6AAADDUAAA5vT7aLY0dERUYAABQgAAAAHQAAACAASAAET1MvMgAAAWQAAABPAAAAYFXHJUtjbWFwAAAGPAAAAZYAAAM67rbLAmdhc3AAABRAAAAACAAAAAgAAAALaGVhZAAAAQgAAAAyAAAANgMWR7xoaGVhAAABPAAAAB0AAAAkB2EDAGhtdHgAABRIAAAAbAAAAGw9xwbVbWF4cAAAAVwAAAAGAAAABgAbUABuYW1lAAABtAAABIcAAAu7KDUzBHBvc3QAAAfUAAAAEwAAACD/uAAyeNpjYGRgYGBkcNRb8/RoPL/NVwZu5hdAEYYLOkzyCPq/BfN8ZgUgl4OBCSQKADP9CZ0AAHjaY2BkYGA+8F8ASF5hAALm+QyMDKhAGgBY0ANpAAAAAABQAAAbAAB42mNgYvJl1GFgZWBh2sPUxcDA0AOhGe8yGDH8YkACCxgY6gMYGLxgfA8153wgpfJAiFnhvwXDCeYDDB+AfG6QHOM/pj0MCkDICAC/ww9/AHjatVRNb9tGEB1ZcvyROIh9TFFg2wZG0kqyqCi2k1NRA45zrGOkyHFFrkTaIpdYLq0IyKG3Hoqi1x76J3rpD+if6K8p0LfDVUzFieoCrQhpH2dn9r03OxARPWj8Tg2qPl/jW+EGfYG3Cq/QGoUeN+kzOve4VctZpS360eNb2PnF4zWS9KvH68j5y+ONGt5c2W5senybdpqfeHynhrdqOXfpy2bH43s1Dds1vMO4SY3WBt6+b37ncYOOm396vEJ3W5963KRvWl953KrlrNL9VurxLVpv/eDxGv3R+tnjdbq/+q3HGzW82fp89cLj2/Rg4yeP79TwVi3nLp1t/ObxvZqG7RrecfhI5zOTjGMrHh49Ev1eb7/tfg/EiVajiTJiVxzproitzZ/t7U2n066d5XpsZB7PuqFOF+tPdo+0eCsWU07VuJxIExwE/cFB5/BwcDDo9HvBk95+/3GnP8BPMOj1g6evlCkSnYmgi91jndnn2sYyFae6zCIViaQQUlgjI5VKcyH0aFFjW0zjJIxFKmdiqIRR46SwyrjCTITKWIn1vDRJESWhBVHRXag/i0FQ6JGdSqMcmY2VyI3OUTq7xiZe65KpMm1FiCa0RaqjZIQ1Aq9JhqVVbaGNiPQ0m2gZ4bwaAW8lWWHlZCISK8oczmU2w1lpjlLDCbEurNsdGZ3y7kSH0mlnfiOqzlstykItnu8MFOXwXIW877ycKZMWzshLZS6TUAk5NkqlKkNGLK1QbyC8QO/sVKlMzGBQZtF7tl+M4Bgno9FX5VVlm0vmPbmuaARDzkNemlwXqiuOEUi105phL2VjbZFPlETtZVLA+Efnbm+qhiPMSGehoSEiEo4XNcPb9QPEP87j9Zqbq6Ej0pTTjAwlNKaYLAl6iOgjrH3q4dmn9jt8AHSCCkUjmuDX4H0XX3dKF6urtzjvGe3hmfLTRWSGmMb5Bn+NObJmiIaIpEv5T3C22xf0Ft9lp5xCy5hKaJLYDaAzgOIB1g4d4nFoAOxcBPSEXfXpMUcGHgVAPeCAntIr9lZAk6YM3AGYqtpjjlh6jtVCgwS7AL8Ge0YR6iK8J6gV2HOqnVoXT1nbBWIa3VvWR9fvKc5O4C4GdpUzrENkCuQ6r47BcuWc0ekMOWKRX72fQ5Xh3IhPs95RAZaP858xt3NQsFYLNZKZ5s6cc/eWI+rur2Kd3cCboNfcqytXGXdS8E26SWjznmbFI/8eeb/OyxDVznmb2QzvaijMwKa515W+Dzu4qkq4D65XEzzu3akoecYyvr2M9VUTlntWUzshxlpwVVU74m6ktVqnKMTbvO9X/g3f5NXMW57zEueppfrFu3iJTpwjEtbq5/dyxkpTzqxu5CVHLnkKFCsc83luLhVPtPDz7JCiN77jhZ87p0BxpoCz6gYlT/zy237B7Bmrc5qrif4Qe52zXWN5f05u0qORv6H5PeTc8ZzvS7GuY5+R8qr8PFR1ae3G2lztnEnPe8ms1Y3/+/+7Pe7jkJmc786SCQ19jvR3vKzP1b3dRIH4D/4fb8LzP/Tmb7O8aiYAeNqtks1LlFEUxp9n0vG7cT4cR5HBIFyIiJBJrRRE1IWFC7VoIYorQ0aTwUEkkOgfiHARIX4iIrgSQUWEIQZDRcr2+hKBa0Ut0HO84ztOgotx4XO4H4dzL7+Hcy+AB7BHCWhmOKpNxqs8zREwawR1SMczPMJjPEENnpu8Ac14gVfoQQiDCGMIw5jELn7gFOd00UMf/QywmGUsZwUrWcV6NrCRLXzJVraxg6/5hp3s4lv2McQBDjLMYY7wPdVRFBwNfgh+PPCoGgelhlyFp8ZDnNyUJL9LkjcN+Qh/Ddl9f2S1dF9/6Z7+1G3d1JhGdUUXdUandFIndFwjgNbGe6amf/JPzuREjuVQ/shvsWRfdmRLvktMvklUNmRd1mRVlmVJFmRe5mRWpmVKxuWrfBHfxbk1Zn22PpVm2q+QQu1mdKPXzP24P+UlwpUI743wJ8Jj6qATKW3SYX+ra6WlOzOQmYXsHDvPtYl46Ipv8pPn3DfueP5vvYCvwPALgUDSb/5trDcuv1EKe14U3bEleS6j25VL40WT/QAAeNpjYGYAg/9bGYwYsAAALMIB6gB42k1WC3wU1dWfPGbmlsci6uCn1tkEDCTKQ0FQMDzSlBBRJDyCoH4oKgUpJTQkDXls9jGv3T2Zmd2Z3Z3dhDfK61NaFcqnolR59KP5qgjVtvgA+SH0V6FqrdyJd/1+353QWn73l5u5e889555z/v9zbgFTXMwUFBSwNQ1rmryPcvc6xv1hgXtboXtbkTuseMmgIiCPfzuhbx+LRwyxb2MYH7oeLx7KFBUUoNqHVj7dsG5184rqhrWtjc+uWNlUUl5dUTL+rrsmjfbme0tqG5b/ZPXyxpKRJdUNY0tWNjWtnTJuXEtLy9im1rUNKxqXrV3ZOvbphp/1W6fm6R9TyLDMUOZ65gbmRmYYcxNzM3MLU8qMZCqYO5hxzGRmJlPHLGAWMouYxcxjzJMFGnNrIT02lZnBtBeMLggWvF5YVrip6OaiTLFQbLGzWWCPsee4Cm4z93/8HF5FDPoxOvYD3w8eGDzgdvJ4sRv9tiMf5U4uEfC3QGblb2HJ4/laAfpkPCM/iMXr3UECfCeTGe4gtmGugKkE+RZYHznsI1/jIvyIIFmybVuWLfa4LWwulAmIQS4QCgX8se8KhbX8+lxg06ZcbpO4g98UyK1fHwisF3278Bt9vxCW88QXnTANRsKo4wvxHasQeYmfaj+8Z8GhqKGYEeiEYJBOEVOxlHfmnfzpORlV8p2ZUDabyWTFP/N4qHn+A/gGLj94hIz+L4Rf4H+jvN5y8BlLScSTkAMnQ6e0moxY9a88sr06iV7hs6FMZ2co1CniFfm3BJg+e96oGMK7eDxszd5lUIPyHP6rAKd6j17SEXmeJ8Ken+6Hd5HvCr4SFHANZvFUXO/XeVxPivD9pIYOlkwl9WKMJ/W4iNyPa0T9NYGUjcNj8CRP8N7P8B24DJddJKPJvZ7YpLvJnaRM9JEteNZWIeAEc7mMkxP7yvlsxGkXY1wIwtGQhohvKRvSJAWCEEyHHTDB7EroCHMvs77OA9uFQCacE91aLpfJ5Lyw+/MDAa/Ci1g8BBcf6oXPEbVeMP4TMlAkA+DBR+omRrW4Chp0ZsJZSEHSTFhvfXBk/1k4A+/XwV0Iqp6ZS9BwRJKklZVkTYEI8lm4lzo++MrH2Ee9AXwj4Y+Tm22EO/BGNpE0bbBQNpzqFPPD+7Pu3cqP/wakjWxkFTmqgII8g+JzHL7+Yn2FP8aPq3xojDgBan+18PdaQkpEIODlOQCyKRva4VlnHsMFgHw6fpsaLv3751jwwjh0+KfkVnE2LG1f2ow24G58GtjvPSdfcFRHJL4etZF9bLzD7EzLtprSHNgAr718ARBmT9eWU9Mjp80gReJMmLW37rCaiJgSNRui8YWIodjSkYVnl56npvEZalm8chn/R79lwp0jN4iEg9lznp6l4lUXcQUeDv8DB5vfeCqhJWL9UHPolNKSchItODD/uSpA5EekiFSSFdQqkLI9M4/O27+st+EUIJPCg530xy+o7k8/PId5XHS6+k4KjPKqyYQVfTvwu2EBj8LsRxh5Ef+49viEXSd2Hj8En/QnlPDvk8F08FWkgJ6C+44/cqJhwpraOTAZUXRRV6fgUaJ7a3H5fUc/pQpOf3jkq68+nF9JZSfeN69cJJeKiTDtxGm6de7i7zCHuYsP3UM3K6fVEEH04Vep7/diHx6P1/YnvOTZ0/VvLdv/8K4Z1KeRo0qJQD0ig74cg0tFXAjv/u6VUzb5STnFdCnMhUXb619VErKuXA1s4Cp50W+e7H32Y6B5OyWQospTl6nmSyfPU9/RJ5Xl1PiE6XdTmPrcwa5GJglfwpkd7x8wdNMECyzFkiEKajwWr1r24+YKeguFTMe1uAmvw1X4QdyO2/AM8gB5kJRVzZk5f9WeI35wjOeSe9GLlAxGT7i73SsikWgHCtWxTQeW/vcUqqOYDC4lI0o/rL7kPw1v7t/35ob5B1e8B+jspVN4Ol5BFuA5JEZHPXmMSETC88kSnPIvwnuFqQvfOIuLPzt74Y+H51ZWTBw9xu97Bw8b5v4n55Ulr8D489X4RXfoNeuheKc77Zr1Yi4QDAb83/2Q9/hPo3731/8sBQ4tBfiYu5Ac479f993O54JOwDsikrfzC/Hb/177yMe46Jqz18r68Nyvt9A6Ecp5TBHB/cJtzl9h7bAtpykOOSeVdvy07ngc8rgrQv5cfrX7OSunpGQIkHT1lj488A+bhc50KCtmwLKsFMIS7sUqeYdNSkk1DVkP/g5Y0aRiIQL4JN0/ypoJIwlJyIYznRACWZYjiLSSg6QDH2IVW0mEr9b3IOU9RQzCEXKYGOQPrKb2Fw3fEbe3b4nQHUoHAuFwh0iO88t6HzhaRnM3hAwdSaZ4MJyCh5bjIeKX8L/HDryDxvIdtPrk0ulukVjuo8I3X00gN3liw8rGl5aM/RTfIlIG3Xb+I1wk+n6FT1Gkj6Yt7Do8wuP5CFKIfRTGoylvryMjvFI9AhcSH75T1F8VyIBxl/EQT27Qub/hwXjAxQoyxJMZdE85GUzT8MRftghXzdNQ4zrKnPsufYSZdE9X2qsN3SGnA6phfP0T5Qhfx191i4bcV4ozYeHyn49e8Nj22cTdk7f9aEvNFjhCyf7mqy+9Jx6Eg+0Hfm7EvDqThUzGm2RLMR/d+fDGhYDKa+omeyXmrouNn6w72dLbDHNpGairX14jPgwLNi96STMUykaaghCdpIRkRg8986e1J2iZS7sb3MA1Ad7Bl06bPur2uhP/EPFe/t+/H6Bt+oMJWBD/Akdee/G3qIr/3k8fzuCULOgcbSh2ohvhke5EXJafyCY6UlIWkM45kLYTOYTvd59g9YTuIcKhcPPKfSQaRqQiP5OUuzNZLSPbAUAxrhNkSQshUt6/Uc1qjpTyxIPe/VVd0VWqLP8EmwikJYd68eiZYW4p56TTjhNOB/3k74Bdt5JNWhR9Nuri06F0UMzfwAXD4aDXR/34PBA3X3m1OUkozoczYUf0XjOlri7YsiVJsiyJ7fkW1qOO6PR3WL/eVyhc84S55mHju4Cf3yiUDLA2CKUD6n4tDB/QXUUntXjEAHw+8c+v/OQPhN1WuMfkEgDxLhlZ22QuLgPtyEjb6HAW6DE9hOzNi2XrKZl7TxJGDHDrSZWQv9C3z73AkZHfzRO6wU515Sgv4xFVlgCFFau7J5m0/TYYmhlE9la6pbCaqRoyoEBnsLUtE9roJ9d/JCixhG3pyWRCVyUppqr+O+8Xtlnqc7lGVd5mKYe4cIyNdWldUao1onT647JsNSr8RVl43pJ6OD1hmDrQYGlGzDANw0xEDVWkr4loVELpVjlJZdt/LyTBtFlDNaMWIMd0Uo5iR/wKqNGYgnZQKf71JQI9oqmmZvlTQN8PaZTdQyNitQHICZBaIpuTdNXYv2IBnCYzHFfpCTCMOG0EiIzB3wjQ1B3Y1pzZYPXABrQt2N3WHgq2iW+TK4IFXSZLr0gv4Kmn/aNnnQI26Lpu0BeUETU0ZGUVLqayMUPTVYiASqsNtG+nxiEWi9FOA1QoiWTuKXwTjbhjZFINext2t24IhdQAdMDqrU27AWXvECI0RC28ZKq2aINp6imk6mxcpUoAReO64d+ctTozPB6OZwupjp7wRkA7t27bs6d5S4O/EdYH2tfFdrRk1saTaYOyGu1d9fKc2mXLnhRhTbp1S/Oi1jWrYRksOvj0b2E/vJjbueeFZ7eGdsOvYe8v9aNI1tlwWzD4C2iBNqdxV/fmnmx3CpHlpEPYamndXNIw6ZWimtiqyVstZRNvR5MRUQZNi8oo3dafMNzymEBzEqfhjcU0M2qqCYsmF5IoSR/NYVqyRcq4qKnJMUWl4ZGSikP5m6CNmSIsnqBxNRK6hdQuNq7F4zGgQ49RcNCRRAmLW7lWUDQz6QdTN3Q9oVIDSjQWpZKI3PpLIW3Qn7viIAI97AHLrwZ4fJMpUGEKt2hUBC0WjdKrxQwwEGHxIaGn3enIdmx6IbG9aVskHAit70RvkT/9i31k3UphlyVt3NoqyfT/Pttaw8l2e3MP/ZDtpyTeXZzsB6BmRE0PxibNtd/XN+xG9wvBvoEpLigYdU/N4q6sQmsOCkUiwaAtZf0ZCiXdppCgUIxRwspRI+UfmNA1yR/gUlSNOFCNmk6G0iJhaKEgBbh/oJNKOU7EDgYjUrAzJTn+gf8Pvh7eOQAAAHjaY2BkYGDgA2IJBhBgYmAEQikgZgHzGAAFaABNAAAAAAEAAf//AAoB9AAAASwAAAD8AF0CeAA9AsYAQQFPAB4CTgAsAmIANwJdADwCggBAAnYANwKCAEID1AA1Ap4AaAL4AGgBEgBvAxYAaALSAEkClAA8AoAAOgGQAF0B8QAzAmUAUwNdADoCKgA9APwAXQK2ADJ42u1VwXLTMBC98xU7PjAwE9uJCU0Axz1kpkCPEA4cFWsdq1haIclx/fesDWkDCW0/oBdJ1mrf7tt9s84vb3UDe3RekVlFs2QaAZqSpDK7VfRtcxUvo8viRa4xCCmC+PtpkbdG/WxRSVCSrxazbL6Il8v5Yh5n09nb6UX2Js7mvMzm02z2LoK0yPdoJDkwQuMq+kTYVOjgpdD2A1w5dBhfk0EfQeuaVVSHYN+nadd1Segt7ZywdZ+UpEeoRpVoPD41+MOIaYfbikyIPVWhEw6jYlMrD4dP4HOoEawjiy70QBVw+lVzl/6aEvhOLWjRg6EAJdl+ApqLWfEulQ9ObduAE2D+kjrTkJCMeRRkNCnjg2gaUAFaSwaE6RlLW3Z144OafBislSM9WhsqReC2jPEdOLWrAwSClosT/iXh2+0NlqN94LNBp/1A5iu6PRcUxM4hajT8ohYB8JYT97DF0CEa6JmgMPIM9c8Vs2b0sj6C+O09Gd0OdTnNqmJSAw/bOkseE7jiC01DvoZteiQ3AdugYN+98kz+6Y0ca1byjWDWp3kzx1MQeFRPefpHfkUu0ZdO2SHJZ808a+YhzRxLJR+aPda9WB9O8Gr9GrLp9GIyrIszof/LIU/v8fLghEQt3I/iI3FLNHyh1kiUQzMF3FnPCnICXa24I0PttwgOd9wPnszsbKBkHQveb1qnvFTlwMQneXof8DCW8fEZzzM8Pfxail+UKUFL); font-weight:300; font-style:normal; } \ No newline at end of file diff --git a/docs/static/fonts/332720/C32E9F0C757C29D4A.css b/docs/static/fonts/332720/C32E9F0C757C29D4A.css deleted file mode 100644 index 96c8c1f725..0000000000 --- a/docs/static/fonts/332720/C32E9F0C757C29D4A.css +++ /dev/null @@ -1,19 +0,0 @@ - -/* - Copyright (C) 2011-2015 Hoefler & Co. - This software is the property of Hoefler & Co. (H&Co). - Your right to access and use this software is subject to the - applicable License Agreement, or Terms of Service, that exists - between you and H&Co. If no such agreement exists, you may not - access or use this software for any purpose. - This software may only be hosted at the locations specified in - the applicable License Agreement or Terms of Service, and only - for the purposes expressly set forth therein. You may not copy, - modify, convert, create derivative works from or distribute this - software in any way, or make it accessible to any third party, - without first obtaining the written permission of H&Co. - For more information, please visit us at http://typography.com. - 171247-88474-20150623 -*/ - -@font-face{ font-family: "Gotham Rounded A"; src: url(data:font/opentype;base64,T1RUTwANAIAAAwBQQ0ZGILkPphQAABIUAAAk2kdERUYAkAAEAAA28AAAACBHUE9TuESiiwAANxAAABwCR1NVQunFLUgAAFMUAAAAgE9TLzJVxiUrAAABQAAAAGBjbWFw0U4uVAAADVwAAASYZ2FzcAAAAAsAAFOUAAAACGhlYWQDcke+AAAA3AAAADZoaGVhB74DqgAAARQAAAAkaG10eNbiGPsAAFOcAAABjG1heHAAY1AAAAABOAAAAAZuYW1lKDUzBAAAAaAAAAu7cG9zdP+4ADIAABH0AAAAIAABAAAAAQBBj0s7+V8PPPUACwPoAAAAANAsAh8AAAAA0CwCH//o/zgEEwMiAAAACAACAAAAAAAAAAEAAAPA/xAAAARO/+j/6AQTAAEAAAAAAAAAAAAAAAAAAABjAABQAABjAAAAAgIsASwABQAEArwCigAAAIwCvAKKAAAB3QAyAPoAAAAAAAAAAAAAAACgAAB/UAAASgAAAAAAAAAASCZDbwAAACPgEgMg/zgAyAPAAPAAAAALAAAAAAH+ArwAIAAgAAIAAAAkAbYAAQAAAAAAAABAAAAAAQAAAAAAAQAjAEAAAQAAAAAAAgAHAGMAAQAAAAAAAwAhAGoAAQAAAAAABAAjAEAAAQAAAAAABQANAIsAAQAAAAAABgAEAJgAAQAAAAAABwBhAJwAAQAAAAAACAANAP0AAQAAAAAACQANAP0AAQAAAAAACgIRAQoAAQAAAAAACwASAxsAAQAAAAAADAASAxsAAQAAAAAADQIRAQoAAQAAAAAADgAqAy0AAQAAAAAAEAAjAEAAAQAAAAAAEQAjAEAAAQAAAAAAEgAjAEAAAwABBAkAAACAA1cAAwABBAkAAQBGA9cAAwABBAkAAgAOBB0AAwABBAkAAwBCBCsAAwABBAkABABGA9cAAwABBAkABQAaBG0AAwABBAkABgAIBIcAAwABBAkABwDCBI8AAwABBAkACAAaBVEAAwABBAkACQAaBVEAAwABBAkACgQiBWsAAwABBAkACwAkCY0AAwABBAkADAAkCY0AAwABBAkADQQiBWsAAwABBAkADgBUCbEAAwABBAkAEABGA9cAAwABBAkAEQBGA9cAAwABBAkAEgBGA9dDb3B5cmlnaHQgKEMpIDIwMDYsIDIwMDcgSG9lZmxlciAmIENvLiBodHRwOi8vd3d3LnR5cG9ncmFwaHkuY29tQ29weXJpZ2h0IChDKSBIJkNvIHwgdHlwb2dyYXBoeS5jb21SZWd1bGFyMTcxMjQ3LTg4NDc0LTIwMTUwNjIzLTI0MjMtMTQwMjE5VmVyc2lvbiAxLjIwMUZvbnRHb3RoYW0gUm91bmRlZCBpcyBhIHRyYWRlbWFyayBvZiBIb2VmbGVyICYgQ28uLCB3aGljaCBtYXkgYmUgcmVnaXN0ZXJlZCBpbiBjZXJ0YWluIGp1cmlzZGljdGlvbnMuSG9lZmxlciAmIENvLlRoaXMgc29mdHdhcmUgaXMgdGhlIHByb3BlcnR5IG9mIEhvZWZsZXIgJiBDby4gWW91IG1heSBub3QgY29weSwgbW9kaWZ5LCBkaXN0cmlidXRlLCBvciBkb3dubG9hZCB0aGlzIHNvZnR3YXJlLCBvciBpbnN0YWxsIGl0IHVwb24gYW55IGNvbXB1dGVyLCBvciBob3N0IGl0IGZyb20gYW55IGxvY2F0aW9uLiBZb3VyIHJpZ2h0IHRvIHVzZSB0aGlzIHNvZnR3YXJlIGlzIHN1YmplY3QgdG8gdGhlIFRlcm1zIG9mIFNlcnZpY2UgYWdyZWVtZW50IHRoYXQgZXhpc3RzIGJldHdlZW4geW91IGFuZCBIb2VmbGVyICYgQ28uIElmIG5vIHN1Y2ggYWdyZWVtZW50IGV4aXN0cywgeW91IG1heSBub3QgdXNlIHRoaXMgc29mdHdhcmUgZm9yIGFueSBwdXJwb3NlLiBGb3IgbW9yZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpc2l0IGh0dHA6Ly93d3cudHlwb2dyYXBoeS5jb20vd2ViZm9udC1zb2Z0d2FyZSwgb3IgY29udGFjdCBIb2VmbGVyICYgQ28uIGF0IHd3dy50eXBvZ3JhcGh5LmNvbSAxNzEyNDctODg0NzQtMjAxNTA2MjMtMjQyMy0xNDAyMTl3d3cudHlwb2dyYXBoeS5jb21odHRwOi8vd3d3LnR5cG9ncmFwaHkuY29tL3dlYmZvbnQtc29mdHdhcmUAQwBvAHAAeQByAGkAZwBoAHQAIAAoAEMAKQAgADIAMAAwADYALAAgADIAMAAwADcAIABIAG8AZQBmAGwAZQByACAAJgAgAEMAbwAuACAAaAB0AHQAcAA6AC8ALwB3AHcAdwAuAHQAeQBwAG8AZwByAGEAcABoAHkALgBjAG8AbQBDAG8AcAB5AHIAaQBnAGgAdAAgACgAQwApACAASAAmAEMAbwAgAHwAIAB0AHkAcABvAGcAcgBhAHAAaAB5AC4AYwBvAG0AUgBlAGcAdQBsAGEAcgAxADcAMQAyADQANwAtADgAOAA0ADcANAAtADIAMAAxADUAMAA2ADIAMwAtADIANAAyADMALQAxADQAMAAyADEAOQBWAGUAcgBzAGkAbwBuACAAMQAuADIAMAAxAEYAbwBuAHQARwBvAHQAaABhAG0AIABSAG8AdQBuAGQAZQBkACAAaQBzACAAYQAgAHQAcgBhAGQAZQBtAGEAcgBrACAAbwBmACAASABvAGUAZgBsAGUAcgAgACYAIABDAG8ALgAsACAAdwBoAGkAYwBoACAAbQBhAHkAIABiAGUAIAByAGUAZwBpAHMAdABlAHIAZQBkACAAaQBuACAAYwBlAHIAdABhAGkAbgAgAGoAdQByAGkAcwBkAGkAYwB0AGkAbwBuAHMALgBIAG8AZQBmAGwAZQByACAAJgAgAEMAbwAuAFQAaABpAHMAIABzAG8AZgB0AHcAYQByAGUAIABpAHMAIAB0AGgAZQAgAHAAcgBvAHAAZQByAHQAeQAgAG8AZgAgAEgAbwBlAGYAbABlAHIAIAAmACAAQwBvAC4AIABZAG8AdQAgAG0AYQB5ACAAbgBvAHQAIABjAG8AcAB5ACwAIABtAG8AZABpAGYAeQAsACAAZABpAHMAdAByAGkAYgB1AHQAZQAsACAAbwByACAAZABvAHcAbgBsAG8AYQBkACAAdABoAGkAcwAgAHMAbwBmAHQAdwBhAHIAZQAsACAAbwByACAAaQBuAHMAdABhAGwAbAAgAGkAdAAgAHUAcABvAG4AIABhAG4AeQAgAGMAbwBtAHAAdQB0AGUAcgAsACAAbwByACAAaABvAHMAdAAgAGkAdAAgAGYAcgBvAG0AIABhAG4AeQAgAGwAbwBjAGEAdABpAG8AbgAuACAAWQBvAHUAcgAgAHIAaQBnAGgAdAAgAHQAbwAgAHUAcwBlACAAdABoAGkAcwAgAHMAbwBmAHQAdwBhAHIAZQAgAGkAcwAgAHMAdQBiAGoAZQBjAHQAIAB0AG8AIAB0AGgAZQAgAFQAZQByAG0AcwAgAG8AZgAgAFMAZQByAHYAaQBjAGUAIABhAGcAcgBlAGUAbQBlAG4AdAAgAHQAaABhAHQAIABlAHgAaQBzAHQAcwAgAGIAZQB0AHcAZQBlAG4AIAB5AG8AdQAgAGEAbgBkACAASABvAGUAZgBsAGUAcgAgACYAIABDAG8ALgAgAEkAZgAgAG4AbwAgAHMAdQBjAGgAIABhAGcAcgBlAGUAbQBlAG4AdAAgAGUAeABpAHMAdABzACwAIAB5AG8AdQAgAG0AYQB5ACAAbgBvAHQAIAB1AHMAZQAgAHQAaABpAHMAIABzAG8AZgB0AHcAYQByAGUAIABmAG8AcgAgAGEAbgB5ACAAcAB1AHIAcABvAHMAZQAuACAARgBvAHIAIABtAG8AcgBlACAAaQBuAGYAbwByAG0AYQB0AGkAbwBuACwAIABwAGwAZQBhAHMAZQAgAHYAaQBzAGkAdAAgAGgAdAB0AHAAOgAvAC8AdwB3AHcALgB0AHkAcABvAGcAcgBhAHAAaAB5AC4AYwBvAG0ALwB3AGUAYgBmAG8AbgB0AC0AcwBvAGYAdAB3AGEAcgBlACwAIABvAHIAIABjAG8AbgB0AGEAYwB0ACAASABvAGUAZgBsAGUAcgAgACYAIABDAG8ALgAgAGEAdAAgAHcAdwB3AC4AdAB5AHAAbwBnAHIAYQBwAGgAeQAuAGMAbwBtACAAMQA3ADEAMgA0ADcALQA4ADgANAA3ADQALQAyADAAMQA1ADAANgAyADMALQAyADQAMgAzAC0AMQA0ADAAMgAxADkAdwB3AHcALgB0AHkAcABvAGcAcgBhAHAAaAB5AC4AYwBvAG0AaAB0AHQAcAA6AC8ALwB3AHcAdwAuAHQAeQBwAG8AZwByAGEAcABoAHkALgBjAG8AbQAvAHcAZQBiAGYAbwBuAHQALQBzAG8AZgB0AHcAYQByAGUAAAAAAwAAAAMAAAAcAAEAAAAAA5IAAwABAAAAHAAEA3YAAACsAIAABgAsACAAIwAvADQANwA/AEQARwBNAF0AXwBjAHEAdAB2AHkAfQCjAKUAqwCuALAAtwC7AMUAxwDWAN0A5QDvAPYA+AD9AQcBDgEQARMBFQEXARkBGwEjAScBKwEtAS8BMQE3AUIBRAFGAUgBUQFUAVYBWAFaAV4BYAFlAWoBbAFuAXABcgF0AXkBewF9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/+cAAAAAAAAAAAAAAAD/8QAA/5z/9v+cAAAAAP/2AAD/8QAAAAAAAAAAAAAAAAAAAAAAFAAA//YAAAAAAAAAAAAAAAD/9gAA//H/8QAAAAAAAAAAAAAAAP/sAAD/7P/x//b/4gAAAAoAAAAAAAD/8QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/9gAAAAAAAAAAAAAAAAAAAAAAAAAA//sAAAAA//sAAAAAAAD/5wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//EAAP/xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/OAAD/9v/2//H/4v/iAAD/2AAA//b/9gAAAAAAAAAAAAD/4gAAAAD/5wAA/87/7P/n/+wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/+cAAP/s/8T/zgAA/84AAAAAAAAAAP/YAAAAAP+c/+z/jf+cAAD/fgAAAAD/9v+wAAD/iAAAAAD/9gAAAAD/+wAA/9j/7P/7AAAAAAAAAAAAAAAAAAD/xAAA/9j/2P+mAAAAAAAA/+wAAAAA/8T/zgAA/8QAAAAAAAD/2AAA/+L/+//JAAD/2P/d/87/xP/YAAAAAAAAAAD/2P/s/+wAAAAA/9gAAP/YAAAAAAAAAAAAAAAAAAAAAAAA/+L/7AAAAAAAAAAAAAAAAP/YAAAAAAAAAAAAAP/7AAAAAAAAAAD/ugAAAAAAAAAAAAAAAP/7AAD/9v/x//YAAAAAAAAAAAAAAAD/+wAA/5wAAP+cAAAADwAAAAoAAAAAAAAAAAAAAAAAAAAAAAAAFAAAAAAAAAAAAA8AAAAFAAAACgAAAAoAAAAAAAAAAAAAAAAAAP/JAAAAAP/dAAD/vwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//sAAP/2AAD/7P/xAAD/5wAAAAAAAAAAAAAAAAAAAAD/9gAAAAD/+wAAAAAACv/7AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAoAAAAAAAAAAAAAAAAAAAAAAAD/8QAAAAD/9v/xAAD/4v/n/+f/4v/2AAAAAAAAAAD/7AAAAAAAAAAAAAAAAAAAAAD/+wAAAAAAAAAAAAAAAAAAAAD/9gAAAAAAAAAAAAAAAAAA//sAAAAA//H/9v/x//H/+wAAAAD/pv/J/5L/8QAAAAAAAAAAAAAAAP/s/3n/ugAA/+wAAAAAAAD/ef/O/5z/g/+c/6b/zv+D/6b/uv/Y/9j/nAAAAAAAAAAAAAAAAAAA/40AAP+m/84AAP+c/5z/nP+c/5z/kgAAAAD/5wAA/+wAAAAAAAAAAAAA//YAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//EAAP/xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/xAAAAAAAAAAAAAP/7AAAAAAAAAAD/nP/YAAD/5wAAAAAAAP/2AAD/7P/2/7oAAAAA//YAAAAAAAD/uv/s/4j/v/+I/9j/5/+//8T/2P/sAAD/2AAAAAAAAAAAAAAAAAAA/8QAAAAA/+wAAP/YAAD/3QAA/9j/yQAAAAD/pv/d/5f/7AAAAAD/9v/2//H/7P/2/7r/0wAA//YAAAAAAAD/v//x/5z/xP+c/93/4v/E/87/3f/x//H/3QAAAAAAAAAAAAAAAAAA/8QAAP+c/+cAAP/d/93/3f/Y/93/yQAAAAAAAP/OAAD/4gAA//YAAP/xAAD/7AAA//YAAAAA//YAAAAAAAD/0wAAAAD/2AAA/87/7P/Y/87/7P/2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/+wAAP/sAAD/2AAA/9gAAAAAAAD/kv/E/37/3QAAAAD/7P/s/+wAAP/2/5z/ugAA//YAAAAAAAD/kv/Y/37/l/9+/7D/2P+X/5z/tf/s/+z/tQAAAAAAAAAAAAAAAAAA/5wAAP+S/+IAAP+1/8T/yf+6/8T/sAAAAAAAAP/YAAD/9gAAAAAAAAAAAAAAAP/2AAD/8QAAAAAAAAAAAAD/5wAAAAD/7AAA/+L/9v/s/+wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/+z/8QAA//EAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/xAAD/tQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/3QAAAAAAAAAAAAAAAAAA//sAAAAA/+z/7AAA/+wAAAAAAAAAAAAAAAD/9v+mAAAAAP/OAAD/ugAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/nAAAAAAAAAAAAAAAAAAAAAAAAAAA//YAAAAAAAAAAAAAAAD/7AAAAAD/8QAAAAAAAP/xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//YAAAAAAAoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/xAAD/uv/x/+wAAAAA//YAAP/2AAAAAAAAAAD/+wAAAAAAAAAA/+L/3QAA//YAAAAAAAAAAAAAAAAAAAAA/+f/7P/i/+f/8QAAAAAAAP/YAAAAAP+m//EAAP+cAAD/kgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/9gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/+IAAAAAAAD/xAAA/8QAAAAAAAAAAP/sAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/8QAAAAD/8QAAAAAAAP/2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//YAAAAAAAAAAAAAAAD/9gAA//b/9gAAAAAAAP/sAAAAAAAAAAAAAAAAAAAAAAAA//YAAAAAAAAAAAAAAAD/7AAAAAD/7AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//EAAAAAAAAAAAAAAAD/7AAA//YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/2AAAAAD/8QAAAAD/9gAAAAAAAP/2//YACgAAAAAAAAAA//H/8QAAAAoADwAAAAAAAAAAAAAAAAAA//v/+//2//sAAAAAAAAAAAAAAAAAAP/OAAD/7P/xAAD/2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/YAAAAAP+c//H/iP+cAAD/fgAAAAAAAAAAAAAAAAAAAAD/7AAAAAD/9gAAAAD/8f/2AAAAAAAAAA8AAP/OAAAAAAAAAAD/2AAAAAD/7AAA/+cAAAAA/6v/ugAA/9MAAP/sAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/sAAD/sP/2/+wAAAAA//YAAP/2AAAAAAAAAAAAAAAAAAAAAAAA/+L/2AAAAAAAAAAAAAAAAAAAAAAAAAAA/+f/5//i/+f/8QAAAAAAAP/YAAAAAP+c//H/iP+cAAD/fgAAAAAAAAAAAAAAAAAAAAD/7AAAAAD/9gAAAAD/8f/2AAAAAAAAAAAAAP/OAAAAAAAAAAD/2AAAAAD/7AAA/+cAAAAA/6v/ugAA/8QAAP/sAAD/2AAAAAAAAP+mAAD/2P/d/87/sP/iAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/iAAAAAAAAAAAAAAAAAAD/2AAAAAD/9gAA//H/9v/i//H/9gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//EAAAAeAAAAHgAeABT/9gAA/9P/9v/TAAAAAP/2//EAAAAAAAAAAAAAAB4AIwAAAB4AIwA3AAAAAP/TAAAAAAAAAAAAAAAAAAD/9gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/zgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP+6AAD/2P/d/+z/tQAAAAAAAAAAAAAAAAAAAAD/9gAAAAD/+wAAAAAAAP/7AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//H/9v/x//EAAAAAAAD/7AAAAAD/9v+mAAD/xP/O/87/nP/xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/9gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//YAAAAA//YAAAAA/+L/7P/T/+L/7AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/xAAD/tQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/4gAAAAAAAAAAAAAAAAAAAAAAAAAA/+z/8QAA//EAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//YAAAAAAAD/2AAAAAD/5wAAAAD/5wAA/+wAAP/n/+z/9gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//YAAP/2/+z/7AAA//EAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//YAAP/2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/sAAD/sP/x/+wAAAAA/+wAAP/sAAAAAAAAAAD/9gAAAAAAAAAA/+L/zgAA/+wAAAAAAAAAAAAAAAAAAAAA/+L/5//d/+L/7AAAAAAAAP/iAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/4gAAAAD/4gAAAAAAAP/sAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//EAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/sAAAAAP/E//EAAP/OAAD/ugAAAAoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/9gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//EAAAAAAAD/3QAA/90AAAAAAAD/pgAA/7AAAAAAAAAAAAAAAAAAAAAA//YAAAAAAAAAAAAAAAD/8QAAAAD/8QAAAAAAAP/xAAAAAAAAAAAAAAAAAAAAAP/dAAAAAAAA//YAAAAAAA8AAAAAAAAAAAAAAAD/9gAAAAD/nAAA/5wAAAAAAAAAAAAAAAAAAAAA/+wAAAAAAAAAAAAAAAD/0wAAAAD/2AAAAAAAAP/YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/+IAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/+cAAAAUAAD/4gAAAAD/5wAA/6b/5/+mAAAAAP/n//YAAAAAAAAAAAAAAAAAAAAAABQAIwAAAAAAAP+1AAAAAAAAAAAAAAAAAAD/9gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/tf/2//EAAAAAAAAAAAAAAAAAAAAA//YAAAAAAAAAAAAA/+z/3QAA//YAAAAA//YAAAAA//YAAAAA/+z/8f/n//H/9gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/5wAAP+c/+IAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/iP/YAAD/4gAAAAAAAAAAAAAAAP/s/78AAAAAAAAAAAAAAAD/sAAAAAD/ugAAAAD/5/+6AAAAAAAAAAD/zgAAAAAAAAAAAAAAAAAA/6sAAAAA/+wAAP/OAAD/zgAA/87/xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/2AAAAAD/8QAAAAD/8QAAAAAAAP/x//YAAAAAAAAAAAAAAAAAAAAAAAAACgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/zgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/+cAAAAAAAAAAAAAAAD/4gAA/6v/5/+r//EAAP/n/+L/8QAAAAAAAAAAAAAAAAAAAAAAAAAA/+wAAAAAAAAAAAAAAAD/8QAA//H/+wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/+wAAAAAAAD/zv/2/+z/5wAA/7r/7P+6//YAAP/s/+z/9gAAAAAAAAAAAAD/9gAAAAAAAAAA//EAAP/EAAAAAAAA//H/9v/2//b/+wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//EAAAAAAAAAAAAAAAD/3QAAAAD/4gAA/+IAAP/i/9P/8QAAAAAAAAAAAAAAAAAAAAAAAAAA/+wAAAAAAAAAAAAAAAD/9gAA//YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/+cAAAAAAAD/zv/2/+z/4gAA/6v/5/+r//EAAP/n/+L/8QAAAAAAAAAAAAD/9gAAAAAAAAAA/+wAAP+6AAAAAAAA//H/9v/2//b/+wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/0wAAAAD/8QAAAAD/8QAAAAAAAP/x//EAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/+wAAP/sAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEABQBbABgAAAAsAAAAGQAAACAAIwAiADMAAAAyAB8AHwAAAAAAAAAAAAEAAgADAAQABgAHAAgACQAKAAAACwAMAA0ADgAPABAAEQASABMAFAAVABYAHQAbAAAAAAAXABoAHgAhACQAJQAoAAAAAAApAAAAKAAoACsAGgAAADQANgA4ADkAHAAAAAAAAAAAAAAAAAAAACYAAAAAAAAAAAAnAC0AIwAjAC4ALwAgAC4ALwAgAAAAIgAmACcAAQAFAF0ADQAAAAAAIQAOAAAAFQAYABcAKQAAACgAFAAUAAAAAAAAACIAAQAAAAIAAAAAAAIAAwAAAAAAAAACAAAAAgAAAAQABQAGAAcACAAJAAoACwAAABAAEgAAAAwADwATABMAGQAaAA8AHQAeAA8ADwAfAB8AEwAfABYAKgAtAC8AMAAAAAAAEQAAAAAAAAAAAAAAGwAmAAAAAAAAABwAIwAYABgAJAAlABUAJAAlABUAAAAXABsAHAAAACYAAgAOAAUABQAAAAcABwABAAkACQACAAsADgADABAAEgAHABcAHwAKACEALgATADEANwAhADoAOgAoADwAPwApAEEARQAtAE0ATQAyAFIAWwAzAF0AXwA9AAEACAABAAAAAQABAAEAAAABAAAACgAwAD4AAkRGTFQADmxhdG4AGgAEAAAAAP//AAEAAAAEAAAAAP//AAEAAAABc3MwMQAIAAAAAQAAAAIABgAOAAYAAAABABAAAQAAAAEAKAABAAgAAQAOAAEAAQBiAAEABAABAGIAAQAAAAEAAAABAAEABv+fAAEAAQBiAAEAAf//AAoB9AAAASwAAAGaAEUCvAAtAzgANwK4ADEA5gBFAa4ARwGuADwBrgBMAmwAQADmADYBmABCAOYAUgH0//oCmAAvAksAQADwAFcA8AA7AmwAPAJsAE8CbABZAhYAJQMWADgC0gBoAuIASQMOAGgCkABoAxAASQIlACoCywBoAmsAaANkAGgDUgBJApwAaANSAEkC0wBoAoAAQQKIADIC+ABdAu4AOAROADwC0gBJAswANgKwAEcBrgBiAfQACQGuADcCWP/oAj4AMwKUAF0COwA6AkgAOgFqAC0ClAA8AmUAXQD5AF4A+f/7AjAAXQD5AGQDtwBdAmUAXQKAADoClABdApQAPAGQACoCRgA1AjoAQwJMADQB4AA3AR4AeQHgADUCRQA+AoQAQgKuADUDPgA1AYYAOgIDADcBoAAiAcIASgDmAFIBhgAvAgMAQwIWADQCEABCA4IAQgDmAE0A5gA7AOYANgGaAE0BmgA7AZoANgHWAG8CqABSATcANwE3AEMC0AA3ArIAFgK2ADI=); font-weight:300; font-style:normal; } @font-face{ font-family: "Gotham Rounded B"; src: url(data:font/opentype;base64,T1RUTwALAIAAAwAwQ0ZGIE+2i2MAABCYAAAOb0dERUYASAAEAAAfCAAAACBPUy8yVcclSwAAASAAAABgY21hcO62ywIAAA08AAADOmdhc3AAAAALAAAfKAAAAAhoZWFkAxZHvAAAALwAAAA2aGhlYQdhAwAAAAD0AAAAJGhtdHg9xwbVAAAfMAAAAGxtYXhwABtQAAAAARgAAAAGbmFtZSg1MwQAAAGAAAALu3Bvc3T/uAAyAAAQeAAAACAAAQAAAAEAQS6s5cVfDzz1AAsD6AAAAADQLAIfAAAAANAsAh8AAP84A58DIAAAAAgAAgAAAAAAAAABAAADwP8QAAAD1AAAAAADnwABAAAAAAAAAAAAAAAAAAAAGwAAUAAAGwAAAAICTQEsAAUABAK8AooAAACMArwCigAAAd0AMgD6AAAAAAAAAAAAAAAAoAAAf1AAAEoAAAAAAAAAAEgmQ28AAAAk4BIDIP84AMgDwADwAAAACwAAAAAB/gK8ACAAIAABAAAAJAG2AAEAAAAAAAAAQAAAAAEAAAAAAAEAIwBAAAEAAAAAAAIABwBjAAEAAAAAAAMAIQBqAAEAAAAAAAQAIwBAAAEAAAAAAAUADQCLAAEAAAAAAAYABACYAAEAAAAAAAcAYQCcAAEAAAAAAAgADQD9AAEAAAAAAAkADQD9AAEAAAAAAAoCEQEKAAEAAAAAAAsAEgMbAAEAAAAAAAwAEgMbAAEAAAAAAA0CEQEKAAEAAAAAAA4AKgMtAAEAAAAAABAAIwBAAAEAAAAAABEAIwBAAAEAAAAAABIAIwBAAAMAAQQJAAAAgANXAAMAAQQJAAEARgPXAAMAAQQJAAIADgQdAAMAAQQJAAMAQgQrAAMAAQQJAAQARgPXAAMAAQQJAAUAGgRtAAMAAQQJAAYACASHAAMAAQQJAAcAwgSPAAMAAQQJAAgAGgVRAAMAAQQJAAkAGgVRAAMAAQQJAAoEIgVrAAMAAQQJAAsAJAmNAAMAAQQJAAwAJAmNAAMAAQQJAA0EIgVrAAMAAQQJAA4AVAmxAAMAAQQJABAARgPXAAMAAQQJABEARgPXAAMAAQQJABIARgPXQ29weXJpZ2h0IChDKSAyMDA2LCAyMDA3IEhvZWZsZXIgJiBDby4gaHR0cDovL3d3dy50eXBvZ3JhcGh5LmNvbUNvcHlyaWdodCAoQykgSCZDbyB8IHR5cG9ncmFwaHkuY29tUmVndWxhcjE3MTI0Ny04ODQ3NC0yMDE1MDYyMy0yNDIzLTE0MDIxOVZlcnNpb24gMS4yMDFGb250R290aGFtIFJvdW5kZWQgaXMgYSB0cmFkZW1hcmsgb2YgSG9lZmxlciAmIENvLiwgd2hpY2ggbWF5IGJlIHJlZ2lzdGVyZWQgaW4gY2VydGFpbiBqdXJpc2RpY3Rpb25zLkhvZWZsZXIgJiBDby5UaGlzIHNvZnR3YXJlIGlzIHRoZSBwcm9wZXJ0eSBvZiBIb2VmbGVyICYgQ28uIFlvdSBtYXkgbm90IGNvcHksIG1vZGlmeSwgZGlzdHJpYnV0ZSwgb3IgZG93bmxvYWQgdGhpcyBzb2Z0d2FyZSwgb3IgaW5zdGFsbCBpdCB1cG9uIGFueSBjb21wdXRlciwgb3IgaG9zdCBpdCBmcm9tIGFueSBsb2NhdGlvbi4gWW91ciByaWdodCB0byB1c2UgdGhpcyBzb2Z0d2FyZSBpcyBzdWJqZWN0IHRvIHRoZSBUZXJtcyBvZiBTZXJ2aWNlIGFncmVlbWVudCB0aGF0IGV4aXN0cyBiZXR3ZWVuIHlvdSBhbmQgSG9lZmxlciAmIENvLiBJZiBubyBzdWNoIGFncmVlbWVudCBleGlzdHMsIHlvdSBtYXkgbm90IHVzZSB0aGlzIHNvZnR3YXJlIGZvciBhbnkgcHVycG9zZS4gRm9yIG1vcmUgaW5mb3JtYXRpb24sIHBsZWFzZSB2aXNpdCBodHRwOi8vd3d3LnR5cG9ncmFwaHkuY29tL3dlYmZvbnQtc29mdHdhcmUsIG9yIGNvbnRhY3QgSG9lZmxlciAmIENvLiBhdCB3d3cudHlwb2dyYXBoeS5jb20gMTcxMjQ3LTg4NDc0LTIwMTUwNjIzLTI0MjMtMTQwMjE5d3d3LnR5cG9ncmFwaHkuY29taHR0cDovL3d3dy50eXBvZ3JhcGh5LmNvbS93ZWJmb250LXNvZnR3YXJlAEMAbwBwAHkAcgBpAGcAaAB0ACAAKABDACkAIAAyADAAMAA2ACwAIAAyADAAMAA3ACAASABvAGUAZgBsAGUAcgAgACYAIABDAG8ALgAgAGgAdAB0AHAAOgAvAC8AdwB3AHcALgB0AHkAcABvAGcAcgBhAHAAaAB5AC4AYwBvAG0AQwBvAHAAeQByAGkAZwBoAHQAIAAoAEMAKQAgAEgAJgBDAG8AIAB8ACAAdAB5AHAAbwBnAHIAYQBwAGgAeQAuAGMAbwBtAFIAZQBnAHUAbABhAHIAMQA3ADEAMgA0ADcALQA4ADgANAA3ADQALQAyADAAMQA1ADAANgAyADMALQAyADQAMgAzAC0AMQA0ADAAMgAxADkAVgBlAHIAcwBpAG8AbgAgADEALgAyADAAMQBGAG8AbgB0AEcAbwB0AGgAYQBtACAAUgBvAHUAbgBkAGUAZAAgAGkAcwAgAGEAIAB0AHIAYQBkAGUAbQBhAHIAawAgAG8AZgAgAEgAbwBlAGYAbABlAHIAIAAmACAAQwBvAC4ALAAgAHcAaABpAGMAaAAgAG0AYQB5ACAAYgBlACAAcgBlAGcAaQBzAHQAZQByAGUAZAAgAGkAbgAgAGMAZQByAHQAYQBpAG4AIABqAHUAcgBpAHMAZABpAGMAdABpAG8AbgBzAC4ASABvAGUAZgBsAGUAcgAgACYAIABDAG8ALgBUAGgAaQBzACAAcwBvAGYAdAB3AGEAcgBlACAAaQBzACAAdABoAGUAIABwAHIAbwBwAGUAcgB0AHkAIABvAGYAIABIAG8AZQBmAGwAZQByACAAJgAgAEMAbwAuACAAWQBvAHUAIABtAGEAeQAgAG4AbwB0ACAAYwBvAHAAeQAsACAAbQBvAGQAaQBmAHkALAAgAGQAaQBzAHQAcgBpAGIAdQB0AGUALAAgAG8AcgAgAGQAbwB3AG4AbABvAGEAZAAgAHQAaABpAHMAIABzAG8AZgB0AHcAYQByAGUALAAgAG8AcgAgAGkAbgBzAHQAYQBsAGwAIABpAHQAIAB1AHAAbwBuACAAYQBuAHkAIABjAG8AbQBwAHUAdABlAHIALAAgAG8AcgAgAGgAbwBzAHQAIABpAHQAIABmAHIAbwBtACAAYQBuAHkAIABsAG8AYwBhAHQAaQBvAG4ALgAgAFkAbwB1AHIAIAByAGkAZwBoAHQAIAB0AG8AIAB1AHMAZQAgAHQAaABpAHMAIABzAG8AZgB0AHcAYQByAGUAIABpAHMAIABzAHUAYgBqAGUAYwB0ACAAdABvACAAdABoAGUAIABUAGUAcgBtAHMAIABvAGYAIABTAGUAcgB2AGkAYwBlACAAYQBnAHIAZQBlAG0AZQBuAHQAIAB0AGgAYQB0ACAAZQB4AGkAcwB0AHMAIABiAGUAdAB3AGUAZQBuACAAeQBvAHUAIABhAG4AZAAgAEgAbwBlAGYAbABlAHIAIAAmACAAQwBvAC4AIABJAGYAIABuAG8AIABzAHUAYwBoACAAYQBnAHIAZQBlAG0AZQBuAHQAIABlAHgAaQBzAHQAcwAsACAAeQBvAHUAIABtAGEAeQAgAG4AbwB0ACAAdQBzAGUAIAB0AGgAaQBzACAAcwBvAGYAdAB3AGEAcgBlACAAZgBvAHIAIABhAG4AeQAgAHAAdQByAHAAbwBzAGUALgAgAEYAbwByACAAbQBvAHIAZQAgAGkAbgBmAG8AcgBtAGEAdABpAG8AbgAsACAAcABsAGUAYQBzAGUAIAB2AGkAcwBpAHQAIABoAHQAdABwADoALwAvAHcAdwB3AC4AdAB5AHAAbwBnAHIAYQBwAGgAeQAuAGMAbwBtAC8AdwBlAGIAZgBvAG4AdAAtAHMAbwBmAHQAdwBhAHIAZQAsACAAbwByACAAYwBvAG4AdABhAGMAdAAgAEgAbwBlAGYAbABlAHIAIAAmACAAQwBvAC4AIABhAHQAIAB3AHcAdwAuAHQAeQBwAG8AZwByAGEAcABoAHkALgBjAG8AbQAgADEANwAxADIANAA3AC0AOAA4ADQANwA0AC0AMgAwADEANQAwADYAMgAzAC0AMgA0ADIAMwAtADEANAAwADIAMQA5AHcAdwB3AC4AdAB5AHAAbwBnAHIAYQBwAGgAeQAuAGMAbwBtAGgAdAB0AHAAOgAvAC8AdwB3AHcALgB0AHkAcABvAGcAcgBhAHAAaAB5AC4AYwBvAG0ALwB3AGUAYgBmAG8AbgB0AC0AcwBvAGYAdAB3AGEAcgBlAAAAAAMAAAADAAAAHAABAAAAAAI0AAMAAQAAABwABAIYAAAAeABAAAUAOAAhACQAMwA2ADkAQABFAEkATgBYAGQAbwBzAHUAdwB6AKEAzwDRAPYA/AEPARIBFAEWARgBGgEmASoBLAEuATABQwFFAUcBTQFPAVEBVQFXAVkBWwFfAWEBawFtAW8BcQFzAXUBegF8AX4B/wIZHoEegx6F4BL//wAAACAAJAAwADUAOABAAEUASABOAFgAZABvAHIAdQB3AHoAoQDIANEA8gD4AQ8BEQEUARYBGAEaASYBKgEsAS4BMAFDAUUBRwFNAU8BUQFVAVcBWQFbAV8BYQFrAW0BbwFxAXMBdQF6AXwBfgH/AhkegR6DHoXgEv///+H/3//U/9P/0v/M/8j/xv/C/7n/rv+k/6L/of+g/57/eAAA/z8AAAAA/wMAAP75/vf+9f7z/uj+5f7j/uH+3/7N/sv+yf7G/sT+wv6//r3+u/66/rb+tP6r/qn+p/6l/qP+ov6e/pz+mv4U/fzhluGU4ZIgCAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABWAAAAYgBqAAAAcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA0ADQANAA0ADwAPAA8ADwATABMAEwATABMAEwAWABYAFgAWABIADQAAAQYAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQIAAAMAAAAAAAAAAAAAAAQFBgcACAkACgsAAAAAAAAMAAAAAA0AAA4PAAAAABAAAAAAAAAAAAARAAAAAAAAAAAAAAASAAAAAAAAAAAAABMAABQVABYAFwAAGAAAAAAAAAAADRAAAAAAAAAAAAAAAAAAAAAAAAATExMTExYWFhYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEwAZAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADQANDQ8PDw8AAAAAAAAAAAAAAAAAAAAAAAAAAAADAAAAAAAA/7UAMgAAAAAAAAAAAAAAAAAAAAAAAAAAAQAEBAABAQEFRm9udAABAQEo+BAA+BwB+B0C+B0D+BYEWQwDi/tc+jP5tAX3Iw+THQAADggS91gRAAMBAQhITGhjb3NsdWdDb3B5cmlnaHQgKEMpIDIwMDYsIDIwMDcgSG9lZmxlciAmIENvLiBodHRwOi8vd3d3LnR5cG9ncmFwaHkuY29tRm9udAAAAQEAAAEAAgAFABEAEgATABQAFgAXABkAGgAhACYAKQAqAC8AOQBFAFAAUwBUAFYAWABbAGABhwAbAgABAD0AQAB7ASwBfwG7AiUCngMZA5YEFQSSBUoFiwXGBeIGKQafBv4HTQeGCAAIRAjGCQ4JSQ0KJPtcBPiI+nz8iAbSWRX3+ov7R/waBftc/EgVi/mE90D8DAX3ePgMFYv9hPtA+AwFb08V90f8Gvv6iwUO+8MO+/P3A/dXFYOShJOTkpKTHpv4dwWZgJZ9Hn8GfYCAfR+J/QIVcAd4mX2enpmZnh6mB559mXh4fX14Hg6o9735dhVlB/sOiDM+iyaLJ8lU9ypqCPuxBz2TTqpTv4iOhY+Ci36Lf3+LfouCj4WShc5R0mvihAg8B36WgJiYlpaYHtkH9xGP5NaL9YvtS8T7LKsI96wHwIW7d7xkkoWQipGLmYuXlouZi5WGkYKSVbNXo0ORCLMHmICWfn6AgH4e92f8wRWLP0pRJ4kI96gH9xZurmGLRgj8BvfqFYvTy8XsjQj7pQf7FaprtYvPCA729/Z/FfdG9wX3PfdVH40H91X7A/c7+0b7RvsF+z37VR6JB/tV9wP7O/dGHo26FfslL/ct9zYfjQf3N+X3Kvcl9yXn+yz7Nx6JB/s2Mfsr+yUeDvug90ehFX2Xf5mZlpeZHvkoB5iCl3seiQaAi4GIgIcI+w5eBYCHg4WLf4t/lYGXi4+Lj4yQjQj3BrIFDn63oxV9loGZHvhIBpmWlpmZgJZ9H/wLi/dq91YF9w/3BL/Li+sIjQf3ATLe+wse+wqLS1dQNYiHioaLh4t+loGYi5SLkY+QksHWxLXgi9+L1VCLMAiLQWRP+wgiCPuR+3kFg4SHhYuCCA6S98t/FfcN9t33Dh+NB4v3FPsHyfsZkwj3fPedBZCRj5OLkgiYgZR+HvwiBn2AgH19loGZH/fui/t6+50FhYSIhYuFCH6WgZgepAb3EudVKR+JBy88TC0eM4tIsFTNh5CDkIKLfYt/f4t9i4SPhI6Hw0ffW/cBiwgOjffCfxX3IfLr9xUfjQf3ESLh+xseSotee151CJz3mvfaiwWZlpaZmYCWfR/77wZ9i3+CingIevu0BYp8j36VhJOGlIeXi5yLurLmiwj3BdpIKB+JByY+QPsDHkWLR65Qw4aQgo+Di32LgH+Lf4uCjoWTg8RU4F7kiwgO999/Ffce9u33GB+NB/cR+wbi+xMe+waLSk1jR4b3auf3Kfcii8iLvHW9YpCHkImRi5mLl5eLmYuUh5GEkQhTt1KkQYsI+0L7A/s8+2cfiQeL+yWqRcVRtWHLb9OLCI+6FfsFNtfvH40H4dvi9wf3A9pDKx6JByhBOfsFHg6m98+BFfcn9wXc9wgfjQeL3UjJM6jQp8m/i94IjQf3AfsH1fsN+w37B0H7AR6JB4s4yVfQbzNuSE2LOQiJB/sI9wU69yce+BsEKDjF4R+NB9rbxPHx21I8HokHNThRKB777AT7FT7Q2h+NB+LnyvcG9wbnTDQeiQc8Pkb7FR4O97l/Ffc39w73MvdwH40Hi/cgadpVwWG1TqhAiwj7Jich+xUfiQf7DPAt9yEe9wKLz8qz05P7Zij7K/shi0+LVqNVuYWQhI2Fi32LgH+LfYuCj4WShQjAYMtp3YsInPfTFfsDPNPtH40H7NLk9wf3CN48KB6JBzM/MfsLHg74DfiH+zYV8IvfptW3jo2Pj4uSi5KFkoSLiIuGiomKQWFEdSmLCPuF+z/3SPd093P3QfdL93v3evdA+0n7S/slQU1FUmqqxB+Ll46kka4IrfdWBY6bgZp7i36LgoKIfAiAUAV0t164OosI+wT7DSH7IyHbQ+wf2ou+tbS+nFK8Z9GLCODs0/c/92f7U/dN+4n7iftV+1v7g/uD91L7WfeUH1b3rhU9VL3g9wTl4ObXw088KTUsLR8OzvcWFvhdBpiWlpiYgJZ+H/xD9634EQaYlpaYmICWfh/8Efen+D4GmJaWmJiAln4f/FgGfX9/fR/9HAd9l3+ZHg73MfOhFX2Xf5mZl5eZHvfG+FT7xgd9l3+ZmZeXmR75JAeZf5d9fX9/fR77wvxU98IHmX+XfX1/f30eDvvd9wOhFX2Xf5mZl5eZHvkkB5l/l319f399Hg73T/OgFX2WgJmZlpaZHov47/h1/PYFk4GThJWLCI8Gl5SVlx/5KAeZgJZ9fYCAfR6L/OL8bPjrBYSUg5GAiwiDBn1/f30fDvcL1J8VfpWAmB6Wi5KSkpQI94P3y/eG+84FkYORhpWLmIuXl4uXi5KIkYWSCPuL99L3g/fFBY+QjpGLkYuYgZZ+i4CLhISEggj7efu8+3z3vwWFk4WQgYt+i39/i3+LhI+FkIQI94L7w/uO+9QFh4aIhYuFCA7E+Mv5WRWagJV9fYGBfB77yQdhy0nFJYsI+w/7ESb7Oh+JB/s69xEo9w8e8IvMxrfOCC4HfJaBmZmVlZoe+5L4WhX18TP7Fx+JB/sWJTIhIC7h9xoejQf3HeTc9wMeDrD3038V9yz3A/cQ9yMfjQf3I/sC9w77K/ss+wP7EPsjHokH+yP3AvsO9ysejbkV+wov7fcPH40H9wzi7vcN9wrnKfsPHokH+ww0KPsNHg77X+igFXyWgZmZlZaZHvdQB4v3OOzc9wCVm4yVl4uZi5qAl3yLQ4syVV8oCPcQB5qAlX19gYB9Hg4h95aBFe3ZxeYfjQeL5TWpOaJCoEagi8QIjQe+ubHRHryLvHu3cY6JkImRi5iLlpaLmIuWhJKFj1qnTp1UiwgoRlA5H4kHizDnct5z0nfLdYtPCIkHUFVlRh5Oi1OfVrGHjoWNhYt+i4CAi36Lg5CDj4i/ZNhw0IsIDpX4nPh9FZqAlX19gYF8HvumByE+PyckUND0HveuB5qAlX19gYF8Hvu3B/sO1jP3FR7oi8S6rccIQQd8loGZmZWWmR4O95b3lIQVjQaYi5STkJoI9yb4Nfcl/DUFkHyUg5iLCI0Gl4uVk5CZCPc7+F8FjZCNkYuRi5eAln2LfYuEgoiBCPsp/EX7KPhFBYeWhJN9iwiJBn6LhIOHgAj7KPxF+yj4QwWHl4OUfYt9i3+Ai36Lho2FjYYI9zv8XwWQfZWDl4sIDlrfFvghBpeVlZeXgZV/H/vyi/f4+DwFkZKOkYuTCIwHlYCVfx78EwZ/gYF/f5WBlx/35Iv7+Pw8BYWEiIWLgwiKB4GWgZceDvvz9yH4jRWThJKDg4SEgx57/HcFfZaAmR6XBpmWlpkfjfkCFaYHnn2ZeHh9fXgecAd4mX2enpmZnh4O5velnRUgCpKcFSEKULYVIgqaQRUiCoYEIwr35JAVIgqGBCMK/DnWFamSgZuPBpCLi4qMhAiSooQGioSLioaLCIedlwaSi42JjYAIk59YhJJihAbRgxUjCvhV+0EV/Ob5tPjmBvsm/VEVmouTlIyZCIMGioKGhIOLCIGFkpqbkZGTH5OLjoePfwiToYMGioUFh4+GjoSLCH1+f3l6loCdH/sS3BWFiZCTko2RkZCNhoODiYaGHys7FaKShqSZcoaEopKFvwaBiQWJjIeMiIsIgYKFfh+KhISScoUH54QVpZKDmwaNkI6PjYsIigeHjomOj46Oj5CIjoYehouHiIiDCJV5hJFyhQd7zRWRi4+TBY6Gj4iSiwiXj5eUl4WTgh+Fi4aIiYUIpnmEkQe7WRWHiIiHho+Hkh+Ui5CRj5UImKqQi4uSeouLhJCLg3eCn5GLi5Jyi4uEkIsFi4uXdI+BioaIiIeLjo6KkoSLCPst9/UVi3SafaJ1lpySm4ucCKJ/mnp7gH96HsL79hWSi4yPBY6JjoiSi5SLkJGLkoubc4WLk4uNjY2Oi4+LjoiOhwiSmIUGiYYFiY6HjYaLgouGhYuFi3ujkIuDi4mJiYiLhouIjoeRCIQGYvcXFZqLl46WlG+ub6l5nICAhn2LfItsoXSpiwiYKhWChISSdweDj4aTHpOLj4+NlAiGjQWKhomJiYsIiIqNjh+fmJJ+lgf3IvdKFZR8m4GdiwinoaKqqnWgbx9yi3h9e3OJpneWcIqRlY6Wi5gIrmqyTUhhYWAei26VeaB1VnlubIthi1a8Y8eLtYutmaeqrGmhgKmLtouur43FCISNBYF6f392i3eLepdyqJqfm5ialAj7Zft8FaGSh5oGkY6Pj4+NiIceeYeEoZKFngeTiJGCHoSLh4eIhAiVeoSRcoUH93dbFYSRB4qIiIeJiYePiI+GkJKOj46LkQiRhpGCgYSEhB6Lho2Ij4eEiYWGi4OLg5GFl4uRi5CNj4+Pho6KkIuTi46QjZIIhowFioeKiomLiYuJjYmOjo+Oj46RCJCSBmhwFYWHj5Efi4+Njo2NkIaPhpCFiImIiomLCPsbrxWVjo2OjYyKix6LioqJh46Jjh+GfQf3F48Vjo2Njo+NiIgei4eJiIiJh4+JjouOCPsF978Vm3uXfJh8nqyQo3SigoF9gHh+CMH72BUgCpKcFSEK+3NoFaiSg52heYOEqJKDtJOSbgaEk3t1m5OSboSTYoMH+FiRFYeIiIeHjoiPj46Oj4+IjocfDvkWFPjvFZMTAAQBASc0RliMmIWUfYsIgIKCf3+Tg5gflouQkY2TCIQGioaIiYaLCISIjpQfC5CNh4MffQaUjo6PHguGiI+Xlo6PkJCOh4B/iIeGHwuXlJSXl4KTf3+Cg39+lIOXHwsAAAEAAAAOAAAAGAAAAAAAAgABAAEAGgABAAQAAAACAAAAAQAB//8ACgH0AAABLAAAAPwAXQJ4AD0CxgBBAU8AHgJOACwCYgA3Al0APAKCAEACdgA3AoIAQgPUADUCngBoAvgAaAESAG8DFgBoAtIASQKUADwCgAA6AZAAXQHxADMCZQBTA10AOgIqAD0A/ABdArYAMg==); font-weight:300; font-style:normal; } \ No newline at end of file diff --git a/docs/static/fonts/332720/CB3CA0F49552DA871.css b/docs/static/fonts/332720/CB3CA0F49552DA871.css deleted file mode 100644 index e78c24bb17..0000000000 --- a/docs/static/fonts/332720/CB3CA0F49552DA871.css +++ /dev/null @@ -1,19 +0,0 @@ - -/* - Copyright (C) 2011-2015 Hoefler & Co. - This software is the property of Hoefler & Co. (H&Co). - Your right to access and use this software is subject to the - applicable License Agreement, or Terms of Service, that exists - between you and H&Co. If no such agreement exists, you may not - access or use this software for any purpose. - This software may only be hosted at the locations specified in - the applicable License Agreement or Terms of Service, and only - for the purposes expressly set forth therein. You may not copy, - modify, convert, create derivative works from or distribute this - software in any way, or make it accessible to any third party, - without first obtaining the written permission of H&Co. - For more information, please visit us at http://typography.com. - 171247-88474-20150623 -*/ - -@font-face{ font-family: "Gotham Rounded A"; src: url(data:font/truetype;base64,AAACAAAABAABABwAAQABAAIAAAAAABgAAAAOAAAAAQAKAD8/AQABAGd1bHNvY2gHAgE/AF0AWgBYAFYAVQBSAEcAOwAxACwAKwAoACMAHAAbABkAGAAWABUAFAATAAcABAADAAIAAQAAAB0AAAAAAAAAAAAAAAAAAAAAAAAAAAAyAD8/AAAAAAAAAgAAZQByAGEAdwB0AGYAbwBzAC0AdABuAG8AZgBiAGUAdwAvAG0AbwBjAC4AeQBoAHAAYQByAGcAbwBwAHkAdAAuAHcAdwB3AC8ALwA6AHAAdAB0AGgAbQBvAGMALgB5AGgAcABhAHIAZwBvAHAAeQB0AC4AdwB3AHcAOQAxADIAMAA0ADEALQAzADIANAAyAC0AMwAyADYAMAA1ADEAMAAyAC0ANAA3ADQAOAA4AC0ANwA0ADIAMQA3ADEAIABtAG8AYwAuAHkAaABwAGEAcgBnAG8AcAB5AHQALgB3AHcAdwAgAHQAYQAgAC4AbwBDACAAJgAgAHIAZQBsAGYAZQBvAEgAIAB0AGMAYQB0AG4AbwBjACAAcgBvACAALABlAHIAYQB3AHQAZgBvAHMALQB0AG4AbwBmAGIAZQB3AC8AbQBvAGMALgB5AGgAcABhAHIAZwBvAHAAeQB0AC4AdwB3AHcALwAvADoAcAB0AHQAaAAgAHQAaQBzAGkAdgAgAGUAcwBhAGUAbABwACAALABuAG8AaQB0AGEAbQByAG8AZgBuAGkAIABlAHIAbwBtACAAcgBvAEYAIAAuAGUAcwBvAHAAcgB1AHAAIAB5AG4AYQAgAHIAbwBmACAAZQByAGEAdwB0AGYAbwBzACAAcwBpAGgAdAAgAGUAcwB1ACAAdABvAG4AIAB5AGEAbQAgAHUAbwB5ACAALABzAHQAcwBpAHgAZQAgAHQAbgBlAG0AZQBlAHIAZwBhACAAaABjAHUAcwAgAG8AbgAgAGYASQAgAC4AbwBDACAAJgAgAHIAZQBsAGYAZQBvAEgAIABkAG4AYQAgAHUAbwB5ACAAbgBlAGUAdwB0AGUAYgAgAHMAdABzAGkAeABlACAAdABhAGgAdAAgAHQAbgBlAG0AZQBlAHIAZwBhACAAZQBjAGkAdgByAGUAUwAgAGYAbwAgAHMAbQByAGUAVAAgAGUAaAB0ACAAbwB0ACAAdABjAGUAagBiAHUAcwAgAHMAaQAgAGUAcgBhAHcAdABmAG8AcwAgAHMAaQBoAHQAIABlAHMAdQAgAG8AdAAgAHQAaABnAGkAcgAgAHIAdQBvAFkAIAAuAG4AbwBpAHQAYQBjAG8AbAAgAHkAbgBhACAAbQBvAHIAZgAgAHQAaQAgAHQAcwBvAGgAIAByAG8AIAAsAHIAZQB0AHUAcABtAG8AYwAgAHkAbgBhACAAbgBvAHAAdQAgAHQAaQAgAGwAbABhAHQAcwBuAGkAIAByAG8AIAAsAGUAcgBhAHcAdABmAG8AcwAgAHMAaQBoAHQAIABkAGEAbwBsAG4AdwBvAGQAIAByAG8AIAAsAGUAdAB1AGIAaQByAHQAcwBpAGQAIAAsAHkAZgBpAGQAbwBtACAALAB5AHAAbwBjACAAdABvAG4AIAB5AGEAbQAgAHUAbwBZACAALgBvAEMAIAAmACAAcgBlAGwAZgBlAG8ASAAgAGYAbwAgAHkAdAByAGUAcABvAHIAcAAgAGUAaAB0ACAAcwBpACAAZQByAGEAdwB0AGYAbwBzACAAcwBpAGgAVAAuAG8AQwAgACYAIAByAGUAbABmAGUAbwBIAC4AcwBuAG8AaQB0AGMAaQBkAHMAaQByAHUAagAgAG4AaQBhAHQAcgBlAGMAIABuAGkAIABkAGUAcgBlAHQAcwBpAGcAZQByACAAZQBiACAAeQBhAG0AIABoAGMAaQBoAHcAIAAsAC4AbwBDACAAJgAgAHIAZQBsAGYAZQBvAEgAIABmAG8AIABrAHIAYQBtAGUAZABhAHIAdAAgAGEAIABzAGkAIABtAGEAaAB0AG8ARwB0AG4AbwBGADEAMAAzAC4AMQAgAG4AbwBpAHMAcgBlAFYAOQAxADIAMAA0ADEALQAzADIANAAyAC0AMwAyADYAMAA1ADEAMAAyAC0ANAA3ADQAOAA4AC0ANwA0ADIAMQA3ADEAcgBhAGwAdQBnAGUAUgBtAG8AYwAuAHkAaABwAGEAcgBnAG8AcAB5AHQAIAB8ACAAbwBDACYASAAgACkAQwAoACAAdABoAGcAaQByAHkAcABvAEMAbQBvAGMALgB5AGgAcABhAHIAZwBvAHAAeQB0AC4AdwB3AHcALwAvADoAcAB0AHQAaAAgAC4AbwBDACAAJgAgAHIAZQBsAGYAZQBvAEgAIAA3ADAAMAAyACAALAA2ADAAMAAyACAAKQBDACgAIAB0AGgAZwBpAHIAeQBwAG8AQwBlcmF3dGZvcy10bm9mYmV3L21vYy55aHBhcmdvcHl0Lnd3dy8vOnB0dGhtb2MueWhwYXJnb3B5dC53d3c5MTIwNDEtMzI0Mi0zMjYwNTEwMi00NzQ4OC03NDIxNzEgbW9jLnlocGFyZ29weXQud3d3IHRhIC5vQyAmIHJlbGZlb0ggdGNhdG5vYyBybyAsZXJhd3Rmb3MtdG5vZmJldy9tb2MueWhwYXJnb3B5dC53d3cvLzpwdHRoIHRpc2l2IGVzYWVscCAsbm9pdGFtcm9mbmkgZXJvbSByb0YgLmVzb3BydXAgeW5hIHJvZiBlcmF3dGZvcyBzaWh0IGVzdSB0b24geWFtIHVveSAsc3RzaXhlIHRuZW1lZXJnYSBoY3VzIG9uIGZJIC5vQyAmIHJlbGZlb0ggZG5hIHVveSBuZWV3dGViIHN0c2l4ZSB0YWh0IHRuZW1lZXJnYSBlY2l2cmVTIGZvIHNtcmVUIGVodCBvdCB0Y2VqYnVzIHNpIGVyYXd0Zm9zIHNpaHQgZXN1IG90IHRoZ2lyIHJ1b1kgLm5vaXRhY29sIHluYSBtb3JmIHRpIHRzb2ggcm8gLHJldHVwbW9jIHluYSBub3B1IHRpIGxsYXRzbmkgcm8gLGVyYXd0Zm9zIHNpaHQgZGFvbG53b2Qgcm8gLGV0dWJpcnRzaWQgLHlmaWRvbSAseXBvYyB0b24geWFtIHVvWSAub0MgJiByZWxmZW9IIGZvIHl0cmVwb3JwIGVodCBzaSBlcmF3dGZvcyBzaWhULm9DICYgcmVsZmVvSC5zbm9pdGNpZHNpcnVqIG5pYXRyZWMgbmkgZGVyZXRzaWdlciBlYiB5YW0gaGNpaHcgLC5vQyAmIHJlbGZlb0ggZm8ga3JhbWVkYXJ0IGEgc2kgbWFodG9HdG5vRjEwMy4xIG5vaXNyZVY5MTIwNDEtMzI0Mi0zMjYwNTEwMi00NzQ4OC03NDIxNzFyYWx1Z2VSbW9jLnlocGFyZ29weXQgfCBvQyZIIClDKCB0aGdpcnlwb0Ntb2MueWhwYXJnb3B5dC53d3cvLzpwdHRoIC5vQyAmIHJlbGZlb0ggNzAwMiAsNjAwMiApQyggdGhnaXJ5cG9DPwNGABIACQQBAAMAPwNGABEA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))); font-weight:300; font-style:normal; } @font-face{ font-family: "Gotham Rounded B"; src: url(data:font/truetype;base64,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cmVlbWVudCB0aGF0IGV4aXN0cyBiZXR3ZWVuIHlvdSBhbmQgSG9lZmxlciAmIENvLiBJZiBubyBzdWNoIGFncmVlbWVudCBleGlzdHMsIHlvdSBtYXkgbm90IHVzZSB0aGlzIHNvZnR3YXJlIGZvciBhbnkgcHVycG9zZS4gRm9yIG1vcmUgaW5mb3JtYXRpb24sIHBsZWFzZSB2aXNpdCBodHRwOi8vd3d3LnR5cG9ncmFwaHkuY29tL3dlYmZvbnQtc29mdHdhcmUsIG9yIGNvbnRhY3QgSG9lZmxlciAmIENvLiBhdCB3d3cudHlwb2dyYXBoeS5jb20gMTcxMjQ3LTg4NDc0LTIwMTUwNjIzLTI0MjMtMTQwMjE5d3d3LnR5cG9ncmFwaHkuY29taHR0cDovL3d3dy50eXBvZ3JhcGh5LmNvbS93ZWJmb250LXNvZnR3YXJlAEMAbwBwAHkAcgBpAGcAaAB0ACAAKABDACkAIAAyADAAMAA2ACwAIAAyADAAMAA3ACAASABvAGUAZgBsAGUAcgAgACYAIABDAG8ALgAgAGgAdAB0AHAAOgAvAC8AdwB3AHcALgB0AHkAcABvAGcAcgBhAHAAaAB5AC4AYwBvAG0AQwBvAHAAeQByAGkAZwBoAHQAIAAoAEMAKQAgAEgAJgBDAG8AIAB8ACAAdAB5AHAAbwBnAHIAYQBwAGgAeQAuAGMAbwBtAFIAZQBnAHUAbABhAHIAMQA3ADEAMgA0ADcALQA4ADgANAA3ADQALQAyADAAMQA1ADAANgAyADMALQAyADQAMgAzAC0AMQA0ADAAMgAxADkAVgBlAHIAcwBpAG8AbgAgADEALgAzADAAMQBGAG8AbgB0AEcAbwB0AGgAYQBtACAAaQBzACAAYQAgAHQAcgBhAGQAZQBtAGEAcgBrACAAbwBmACAASABvAGUAZgBsAGUAcgAgACYAIABDAG8ALgAsACAAdwBoAGkAYwBoACAAbQBhAHkAIABiAGUAIAByAGUAZwBpAHMAdABlAHIAZQBkACAAaQBuACAAYwBlAHIAdABhAGkAbgAgAGoAdQByAGkAcwBkAGkAYwB0AGkAbwBuAHMALgBIAG8AZQBmAGwAZQByACAAJgAgAEMAbwAuAFQAaABpAHMAIABzAG8AZgB0AHcAYQByAGUAIABpAHMAIAB0AGgAZQAgAHAAcgBvAHAAZQByAHQAeQAgAG8AZgAgAEgAbwBlAGYAbABlAHIAIAAmACAAQwBvAC4AIABZAG8AdQAgAG0AYQB5ACAAbgBvAHQAIABjAG8AcAB5ACwAIABtAG8AZABpAGYAeQAsACAAZABpAHMAdAByAGkAYgB1AHQAZQAsACAAbwByACAAZABvAHcAbgBsAG8AYQBkACAAdABoAGkAcwAgAHMAbwBmAHQAdwBhAHIAZQAsACAAbwByACAAaQBuAHMAdABhAGwAbAAgAGkAdAAgAHUAcABvAG4AIABhAG4AeQAgAGMAbwBtAHAAdQB0AGUAcgAsACAAbwByACAAaABvAHMAdAAgAGkAdAAgAGYAcgBvAG0AIABhAG4AeQAgAGwAbwBjAGEAdABpAG8AbgAuACAAWQBvAHUAcgAgAHIAaQBnAGgAdAAgAHQAbwAgAHUAcwBlACAAdABoAGkAcwAgAHMAbwBmAHQAdwBhAHIAZQAgAGkAcwAgAHMAdQBiAGoAZQBjAHQAIAB0AG8AIAB0AGgAZQAgAFQAZQByAG0AcwAgAG8AZgAgAFMAZQByAHYAaQBjAGUAIABhAGcAcgBlAGUAbQBlAG4AdAAgAHQAaABhAHQAIABlAHgAaQBzAHQAcwAgAGIAZQB0AHcAZQBlAG4AIAB5AG8AdQAgAGEAbgBkACAASABvAGUAZgBsAGUAcgAgACYAIABDAG8ALgAgAEkAZgAgAG4AbwAgAHMAdQBjAGgAIABhAGcAcgBlAGUAbQBlAG4AdAAgAGUAeABpAHMAdABzACwAIAB5AG8AdQAgAG0AYQB5ACAAbgBvAHQAIAB1AHMAZQAgAHQAaABpAHMAIABzAG8AZgB0AHcAYQByAGUAIABmAG8AcgAgAGEAbgB5ACAAcAB1AHIAcABvAHMAZQAuACAARgBvAHIAIABtAG8AcgBlACAAaQBuAGYAbwByAG0AYQB0AGkAbwBuACwAIABwAGwAZQBhAHMAZQAgAHYAaQBzAGkAdAAgAGgAdAB0AHAAOgAvAC8AdwB3AHcALgB0AHkAcABvAGcAcgBhAHAAaAB5AC4AYwBvAG0ALwB3AGUAYgBmAG8AbgB0AC0AcwBvAGYAdAB3AGEAcgBlACwAIABvAHIAIABjAG8AbgB0AGEAYwB0ACAASABvAGUAZgBsAGUAcgAgACYAIABDAG8ALgAgAGEAdAAgAHcAdwB3AC4AdAB5AHAAbwBnAHIAYQBwAGgAeQAuAGMAbwBtACAAMQA3ADEAMgA0ADcALQA4ADgANAA3ADQALQAyADAAMQA1ADAANgAyADMALQAyADQAMgAzAC0AMQA0ADAAMgAxADkAdwB3AHcALgB0AHkAcABvAGcAcgBhAHAAaAB5AC4AYwBvAG0AaAB0AHQAcAA6AC8ALwB3AHcAdwAuAHQAeQBwAG8AZwByAGEAcABoAHkALgBjAG8AbQAvAHcAZQBiAGYAbwBuAHQALQBzAG8AZgB0AHcAYQByAGUAAAIAAAAAAAD/tQAyAAAAAAAAAAAAAAAAAAAAAAAAAAAAHQAAAAEAAgADAAQABwATABQAFQAWABgAGQAbABwAIwAoACsALAAxADsARwBSAFUAVgBYAFoAXQCjAQIHaGNvc2x1ZwABAAH//wAKAAEAAAAOAAAAGAAAAAAAAgABAAEAHAABAAQAAAACAAA=); font-weight:300; font-style:normal; } \ No newline at end of file diff --git a/docs/static/fonts/332720/DBA0DCC14F9DF8F4E.css b/docs/static/fonts/332720/DBA0DCC14F9DF8F4E.css deleted file mode 100644 index 9d5f7c8977..0000000000 --- a/docs/static/fonts/332720/DBA0DCC14F9DF8F4E.css +++ /dev/null @@ -1,19 +0,0 @@ - -/* - Copyright (C) 2011-2015 Hoefler & Co. - This software is the property of Hoefler & Co. (H&Co). - Your right to access and use this software is subject to the - applicable License Agreement, or Terms of Service, that exists - between you and H&Co. If no such agreement exists, you may not - access or use this software for any purpose. - This software may only be hosted at the locations specified in - the applicable License Agreement or Terms of Service, and only - for the purposes expressly set forth therein. You may not copy, - modify, convert, create derivative works from or distribute this - software in any way, or make it accessible to any third party, - without first obtaining the written permission of H&Co. - For more information, please visit us at http://typography.com. - 171247-88474-20150623 -*/ - - \ No newline at end of file diff --git a/docs/static/fonts/332720/E62638AD5B5A9C61A.css b/docs/static/fonts/332720/E62638AD5B5A9C61A.css deleted file mode 100644 index a727dfcc29..0000000000 --- a/docs/static/fonts/332720/E62638AD5B5A9C61A.css +++ /dev/null @@ -1,19 +0,0 @@ - -/* - Copyright (C) 2011-2015 Hoefler & Co. - This software is the property of Hoefler & Co. (H&Co). - Your right to access and use this software is subject to the - applicable License Agreement, or Terms of Service, that exists - between you and H&Co. If no such agreement exists, you may not - access or use this software for any purpose. - This software may only be hosted at the locations specified in - the applicable License Agreement or Terms of Service, and only - for the purposes expressly set forth therein. You may not copy, - modify, convert, create derivative works from or distribute this - software in any way, or make it accessible to any third party, - without first obtaining the written permission of H&Co. - For more information, please visit us at http://typography.com. - 171247-88474-20150623 -*/ - -@font-face{ font-family: "Gotham Rounded A"; src: url(data:font/opentype;base64,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AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD8/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAoAAAAAAAAAAAAAAAAAAAAAAAAAPz8AAAAAAAA/PwAAAAA/PwAAAAA/PwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/Pz8AAD8/AAA/PwAAPz8AAAAAPz8AAAAAAAAAAAAAAAAAAD8/AAAAAAAAAAA/PwAAAAA/PwAAAAA/PwAAAAAAAAAAAAAAAD8/AAAAAAAAAAAAAAAAPz8AAD8/Pz8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/Pz8/AAA/PwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPz8/Pz8AAAAAPz8AAAAAPz8AAAAAPz8AAD8/PwAAAAAAAAAAAAA/PwAAAAAAAAAAAAAAAAAAAAA/Pz8/Pz8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPz8AAAAAAAAAAAAAAAAAAD8/AAAAAAAAIwAUAAAAAAAAAAAAAAAAAAAAAAA/PwAAAAA/Pz8/AAA/PwAAAAA/PwAAFAAAAD8/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD8/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPz8AAAAAAAA/PwAAAAA/PwAAAAAAAAAAAAAAAD8/AAAAAAAAAAAAAAAAAAAAAD8/AAA/PwAAAAA/PwAAAAAAAAAAAAAAAA8AAAAAAD8/AAAAAAAAPz8AAAAAAAAAAAAAAAAAAAAAPz8AAAAAAAA/PwAAAAA/PwAAAAAAAAAAAAAAAD8/AAAAAAAAAAAAAAAAAAAAAD8/AAA/PwAAAAAAAD8/AAA/PwAAAAAAAD8/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/PwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAoAAAA/PwAAPz8AAD8/PwAAAAA/PwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPz8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/PwAAAAAAAD8/AAAAAD8/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/PwAAAAAAAD8/Pz8/PwAAAAAAAAAAAAAAAAAAAAA/PwAAPz8/AAAAAAAAAAA/PwAAAAAAAAAAPz8AAD8/AAAAAD8/Pz8/AAA/PwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/PwAAPz8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPz8AAD8/Pz8/AAA/PwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPz8/AAA/PwAAPz8AAAAAPz8AAAAAPz8AAAAAAAA/PwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/PwAAPz8/AAAAAAAAAAAAAAAAAAAAAAAAAAA/PwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/PwAAPz8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/Pz8/Pz8AAAAAPz8AAAAAPz8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD8/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/Pz8/Pz8/AAA/Pz8/AAAAAD8/AAAAAAAAPz8/PwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD8/AAAAAAAAPz8AAAAAPz8AAAAAAAAAAAAAAAAAAAAAPz8/PwAAPz8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/PwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/PwAAAAAAAAAAAAAAAAAAPz8AAAAANwAjAB4AAAAjAB4AAAAAAAAAAAAAAD8/Pz8AAAAAPz8/Pz8AAD8/FAAeAB4AAAAeAAAAPz8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD8/Pz8AAD8/AAAAAD8/AAAAAAAAAAAAAAAAAAA/PwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/Pz8/Pz8/AAA/PwAAAAAAAD8/AAA/PwAAPz8AAD8/Pz8AAAAAPz8AAD8/AAAAAD8/AAAAAAAAAAA/PwAAAAAAAAAAAAA/PwAAAAA/PwAAAAA/PwAAAAAAAAAAAAAAAAAAAAB+PwAAPz8/Pz8AAAAAPz8AAAAAAAA/Pz8/Pz8AAAAAAAAAAAAAAAAAAAAAAAAAAD8/PwAAAAAAAAAAAAAAAAAAAAAAAD8/AAA/PwAAAAA/Pz8/Pz8AAD8/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD8/AAA/PwAAPz8/PwAAAAA/PwAAPz8AAAAAPz8AAAAAAAAAAD8/AAAPAAAAAAAAAD8/AAAAAD8/AAAAAD8/AAAAAAAAAAAAAAAAAAAAAH4/AAA/Pz8/PwAAAAA/PwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD8/AAA/Pz8AAD8/AAAAAAAAAAAAAAAAAAA/Pz8/Pz8/PwAAAAAAAAAAAAAAAAAADwAKAAAAPz8/AAAAAAAAAAAKAD8/Pz8AAAAAAAA/PwAAAAA/PwAAAAA/PwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD8/AAA/PwAAAAAAAAAAAAAAAD8/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/PwAAAAA/PwAAAAAAAAAAAAAAAD8/AAAAAAAAAAAAAAAAAAAAAAAAPz8AAAAAAAA/Pz8/AAA/PwAAAAAAAAAAAAAAAD8/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPz8AAAAAAAA/PwAAAAA/PwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPz8AAAAAAAAAAD8/AAA/PwAAAAAAAD8/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/PwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/PwAAPz8AAD8/Pz8AAAAAPz8AAAAAAAA/Pz8/Pz8AAAAAAAAAAAAAAAAAAAAAPz8AAD8/PwAAAAAAAAAAPz8AAAAAAAAAAD8/AAA/PwAAAAA/Pz8/PwAAPz8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAoAAAAAAD8/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPz8AAAAAAAA/PwAAAAA/PwAAAAAAAAAAAAAAAD8/AAAAAAAAAAAAAAAAAAAAAAAAAAA/PwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/PwAAPz8AAAAAPz8/PwAAAAAAAAAAAAAAAD8/AAA/Pz8AAAAAPz8AAAAAAAAAAAAAAAAAAD8/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD8/AAA/PwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPz8AAD8/PwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/Pz8/PwAAPz8AAAAAPz8AAAAAAAAAAAAAPz8AAD8/AAAAAAAAAAAAAAAAPz8AAD8/AAAAAAAAPz8/Pz8/Pz8/AAA/Pz8/AAA/PwAAAAAAAAAAAAAAAAAAPz8/Pz8/Pz8/Pz8/fj8/P34/Pz8/AAAAAAAAPz8AAD8/Pz8/PwAAPz8/PwAAAAA/P34/Pz8/AAAAAAAAPz8AAD8/AAA/PwAAPz8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/Pz8/Pz8AAD8/AAAAAD8/AAAAAAAAPz8AAAAAPz8AAD8/AAA/PwAAPz8AAD8/AAA/PwAAAAAAAD8/Pz8/Pz8AAD8/Pz8AAD8/AAAAAAAAAAAAAAAAAAA/Pz8/Pz8/Pz8/Pz8/Pz8AAAAAAAA/PwAAPz8/Pz8/Pz8/Pz8AAAAAPz8/Pz8/PwAAAAA/Pz8AAD8/AAA/PwAAPz8AAAAAPz8AAAAAAAAAAAAAAAAAAD8/AAA/Pz8/Pz8/Pz8/Pz8/Pz8AAAAAAAA/PwAAAAA/Pz8/AAA/PwAAAAAAAD8/AAA/Pz8/AAAAAAAAAAA/PwAAAAAAAAAAAAA/PwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/PwAAPz8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAPz8AAAAAAAAAAAAAPz8AAD8/AAAAAD8/Pz8/Pz8/Pz8/PwAAPz8/PwAAPz8AAAAAAAAAAAAAAAAAAD8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/eT8AAAAAAAA/PwAAPz95Pz8AAAAAAAAAAAAAAAA/Pz8/Pz8/AAAAAD8/Pz8AAAAAPz8AAAAAAAAAAAAAAAAAAD8/AAAAAAAAAAAAAAAAAAAAAD8/AAAAAAAAAAAAAAAAAAAAAD8/AAAAAAAAAAA/Pz8/PwAAPz8/PwAAAAA/PwAAAAAAAAAAAAAAAAAAAAAAAAoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPz8KAAAAAAA/PwAAAAA/PwAAAAAAAAAAAAAAAAAAAAA/PwAAPz8/AAA/PwAAPz8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD8/AAA/PwAAAAA/PwAAAAAAAAAAAAAAAAAACgAAAAoAAAAFAAAADwAAAAAAAAAAABQAAAAAAAAAAAAAAAAAAAAAAAAACgAAAA8AAAA/PwAAPz8AAD8/AAAAAAAAAAAAAAAAPz8/PwAAPz8AAAAAAAAAAAAAAAA/PwAAAAAAAAAAPz8AAAAAAAAAAAAAPz8AAAAAAAAAAAAAAAA/Pz8AAAAAAAAAAAAAAAAAAAAAAAA/PwAAPz8AAAAAPz8/PwAAAAAAAAAAPz8/Pz8/AAA/Pz8/AAA/PwAAAAAAAD8/AAA/Pz8AAAAAPz8AAAAAAAA/Pz8/AAA/PwAAAAAAAAAAAAAAAAAAPz8/AAA/PwAAAAA/PwAAAAA/PwAAPz8/PwAAAAB+PwAAPz8/Pz8/AAAAAD8/AAAAAAAAAAA/PwAAPz8/PwAAPz8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPz8/Pz8AAD8/AAAAAD8/AAAAAAAAAAAAAD8/Pz8AAD8/AAA/Pz8/Pz8/PwAAPz8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPz8AAD8/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/PwAAAAAAAD8/AAAAAD8/AAAAAAAAAAAAAAAAAAAAAAAAAAA/PwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/PwAAAAAAAAoAAAA/Pz8/AAA/PwAAAAAAAAAAAAAAAD8/PwAAPz8AAAAAAAAAAAAAAAA/PwAAFAAAAAAAAAAAAAAAAAAAAAAAPz8AAD8/AAAAAD8/Pz8/PwAAPz8AAAAAAAAAAAAAAAA/Pz8/AAAAAAAAAAAAAAAAAAAAAD8/Pz8AAAAAAAA/PwAAPz8/PwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPz8AAAAAPz8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD8/AAAAAAAAAAAAAD8/AAAAAAAAAAAAAAAAPz8/AAAAAAAAAAAAAAAAAAAAAAAAPz8AAD8/AAAAAD8/Pz8AAAAAAAAAAD8/Pz8/Pz8AAD8/Pz8/AAA/PwAAAAAAAD8/Pz8/Pz8/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPz8AAD8/AAA/PwAAAAA/PwAAAAAAAAAAAAAAAAAAAAA/Pz8/AAAAAAAAAAAAAAAAPz8AAAAAAAAAAD8/AAA/PwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/PwAAPz8AAAAAPz8AAAAAAAAAAAAAAAAAAD8/AAA/Pz8/PwAAPz8AAAAAAAA/Pz8/Pz8AAD8/AAAAAAAAAAAAAAAAPz8/Pz8AAD8/AAAAAD8/AAAAAD8/AAA/PwAAAAAAAD8/AAA/Pz8/PwAAPz8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMwA8AD8YPxcAAAQAPxkCAHYAaQBgAF8AWgBXAFUAUAA9ADwAOQA3ADIAMQArACcAIwAaABkAGAAXABYAFQAUABMAEQAQAAsACQAHAAUAHwABABQAEgABAD8/VQA/PzkAPz83AAMA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HmBhYUhNP2o/CD8/Pz8/Pz9wP3c/P3N7fXg/ch9vP3U/Pz8/Pwg/Pz8/fD8VSj8iPwc/fj8/Px8/Pz8/CD8/Pz8/PwU/Pwg/Pz8/Pz8ePz8/Pwd3Pz8/PxUqPwg/P3Q/bD98P30/Pz8/eT9vP28/Pz8/Pz8VFz9iBj8IPz8/Pz8/Pz8/Pz8/Pz8/P3s/Pz8/Pz8/Pz8/Pz8/BT8/Bj8/Pwg/Pz8/Pz8/Pz8/Pz8/Pz9zPz8/Pz8/Pz8/Pz8/Pz8FPz8/PxU/Px56fz97ej9/Pwg/Pz8/Pz91P30/dD8VPz8tPwg/Pz8/Pz8/Pz8/Pz8/P3Q/Pz8FPz8/Pz9yPz8/Pz8/dz8/Pz8/P3o/Pz8/Pz8IPz8/Pz8/Hz8/Pz8/Pz8/FVk/Bz8/eT8IPz8/Pz8/Hz8/Pz8/Pz8/CD8/Pz8/PwU/Pz8/FT97Bz9yPz95Pwg/Pz8/Pz8ePz8/Pz8/Pz8/Pz8/Bz8IPz8/Pz8/Bj8/Pz8VPwc/cj8/Pz8ffj8/Pwg/Pz8/Pz8FPz8GPz8/Pz8/cj8/Pz8/FTsrHz8/Pz8/Pz8/Pz8/Pz8/Pz8VPxI/Hz8/P3p5f359CD8/Pz8/PwU/PwY/Pz8Ifz8/Pz8/Hz8/Pz8/Pz8/CD8/Pz8/PwY/CD8/Pz8/PxVRPyY/Bj8/Pz8VQT9VPwoyFT8GP2I/P1g/Pwg/Pz8/Pz8GPz8/CD8/Pz8/PwY/Pz8IPz8/Pz8/Bj8/Pz8/FT85PwoyBD8KMRU/PwoyBD8KMRVBPwoxFT9QCjAVPz8KLxU/Pz8OHz8/Pz8GPwg/Pz8/Pz8FST8LP0k/Cz8IPz8/Pz8/Bj8ePz8/Pwc/Px4/Pz8/Pz8/PwV2Pz8xPwg/Pz8/Pz8/Pz8/Pz8FMT92Pz8ePz8/Pz8/Pz8VPz9iPwY/Hz8/Pz8/Pz8/Bmc/Hz8/Pz8/Pz8/Bz8/Px4/Pz8/Pz8/PxUpPxM/Dgg/Pz8/Pz8/Pz8/Hj8jPy0/PwY/Hz8/P35+Pz9+BkwIeT94P3g/dD91P3U/Bj8fPz8/fn4/P34GQQgjP2ciJT8WPwg/Aj8/Rz9XPz8/Pz8/Pz8/Pz8/Pz8/Pz8/Rj9kPz8/Pwo/PwY/Px9+Pz8/Pz8/PwY/Pwg/Pz8/Pz8/Pz8/Pz8GPz8ffj8/Pz8/Pz8GPz8IEj9sPzY/BT8/OVxSSV4/Pz8/Pz8efj8/PxUcPyY/DgorFWc/Pz8OCioVP3E/Pw4KLhZ2PwouFnY/Ci4VPz8/Dh4/VD9HBz8eR1RQSks/Tz8HPx8/Pz8/FXg/fz8mPw4KLRZIPwokFTE/Yj8OCi0WSD8KLRU/P2I/DgosFkg/CiwVRD8/Yj8OCiQVMT8OCi0VPz8OCiwVRD8/Pw4fP38/fX1/f30GXj8ffT9/Pz8/Pz8GXj8VPz8/Dh8/fz99fX9/fQY/Px99P38/Pz8/PwY/PxU/Mw4KKRUPPz8IPz8/Pz8/BRU/Pwg/Pz8/Pz8/BD8/Pz8HPx8/P0slCD8/aFFTWj8/Pz8/Pz9+Pz8/Pz8/Pz8/Pz8/Px4YPzM/IAc/CBA/P0krfQg/BQM/Pwh/Pz8/Pz8VPz8/PzkOCisWYD8IPz8/Pz8/BUc/HT8IPz8/Pz8/Pz8/Pz8/BUc/HT8IPz8/Pz8/Pz8/P38/Pz8/Pz8/BUE/Ej9DPxI/CD8/Pz8/Px9/Pz9/FWc/Pz8mDh5QW2JRBz8eT1s/Pz8/Bz8fPz9fURUxPxU/Hz8/Pz8/Pz8/Bj8/Hz8/Pz8/Pz8/Bj8/FQo/Ez8eP0g/PQc/HjxHTjc4P08/Bz8fPz8/PxUvP1Y/dj8OCiAVPz8OHlFaYFYHPx5WWj8/Pz8/Bz8fPz9gUQQ/Hj9HPz0HPx49R0M8PD9DPwc/Hz8/Pz8VMD91Pzo/Dh9yfn14dj8/Pwc/FUE/Hz8/Pz8GSx5nP24/CD8/Pz8/PwU/ZQg/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8FUD8HPz8ePz8/Pz8/Pz8VP0oeNERINgc/HjZFPz8/Pz8/Bz8fPz9JMwQ/Hj88PywHPx4sOz4qKT8/Pwc/Hz8/Pz8VPz9kP1w/DgoqFmA/CD8/Pz8/PwVHPx0/CD8/Pz8/Pz8/Pz8/PwVHPx0/CD8/Pz8/Pz9/Pz8/Pz8/Pz8/PwVBPxI/Qz8SPwg/Pz8/Pz8/Pz8/Pz8VPz0/Jg4fPz8/Pz8/Pz8GcD8fPz8/Pz8/Pz8GcD8VLj8pHlhsXl0HcAg/Pz8/Pz8ePz8/Pwc/Hz8/amUVPz8eP20/Twc/H1BpWEIIP2c/cz90Bz8fWHE/Pwg/Pz8/Pz8IPz8/Pz8/Pz8/Pz8/Pz8/Pz8/fWw/cD9nP2U/bT91P3k/Pz8/BzQ/Hj8/Pz8/Pz8/B3AIPz8/Pz8/FS8/Qj92Pw4ePzY/JAc/HyU0OyQIP1A/ZT9rPz8/Pz8/Pz8/Pz8/Pz8/Pz8/dD94Pz8/Hj8/Pz8HPx8/P00+CD9ee21vbD8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/FSo/Px5SPys/Iz9LPwc/Hks/KT8iP1E/Uj8rPyM/Sz8HPx9LPyk/Ij9RPwQ/Hl8/Nz8yP1k/Bz8eWT85PzQ/Xz9fPzc/Mj9ZPwc/H1k/OT80P18/FX8yP2o/DgZWPx9/Pz8/Pz8/PwdWPx4/Pz8/Pz8/fQYjVj8fPz8/f34/P38GVj8pVj8fPz8/f38/P38FP0Q/Pz8/CD8/Pz8/P30/P38/fT8/Pz8/PwU/Pz8/Pz8/Pwg/Pz8/Pz8/fj8/Pz8/Pz8/Pz8FPz8/Pz9FPx9/Pz8/Pz8/PwZWPxU/PwQ/Dgg/Pz8/Pz8FeT0GPz8fPz8/fn4/P34HSQo/CEA/S3RhYWZmdlc/Tj8pP1E/Xwg/Pz8/Pz8/Pz8/Pz8/Pz8/Pz9dP2k/Pz8/Pz8/Pz8/Pz8/Bgs/Pz8ffj8/Pz8/Pz8GPz8/Pz8/H34/Pz8/Pz8/BnY/Hj8/Pz8VPz8OCD8/VD89BT8/OT8/Hgg/Pw4/Bz8VPz8NPwhnPyc/Bj8/Bz8fIz8QPwY/Jj8FP3xHfgg/Pz8/P34/ez9/Pz8FPz8IP1Q/Yz9pPz8/Pz8/Pz8/Pz8/Pz8/Pz8/bj9xPz8/BUQ/CD9/P38/fwg/S25XX18/Pz8/Pz8/fz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/BT8/CD8/Pz8/Pz8/fj95PxU/bz9oDgopFQI/Px8/Pz8/Bj8ePz8/fQV3P3sePz8/Pz8/Pz8VPz8hPwA/Dgg/PT9rPz8HPx4/P3Qkez8/Pz8/Pz8HPwg/Pz8/PT8/Pz8/fz8/Pz8/Pz9lJT9leyg/B0AIMj9nYnhMdT9qPzI/B0AIKD9lP2UlPz8/Pz8/P38/Pz8/PxVdPxw/Dh5/Pz9/fz8/PwcOPx4/Pz8/Pz8/fxUCPw0/Pw4IaT0/Sz8kPwc8Hj1aPz8/Pz8/Pz97JFp0PQc8CCQ/S2tpPT8/Pz8/Pz8/Pz8/Pz8/JT8/Pwc/CD8/Pz8/P0g/Zj8/Bz8IPz8/ez8lPz8/Pz8/Pz8/Pz8/PxUfPyo/HD8OHj8/Pz8HPwg/Pz8/Pz8FPD8/Pz8fPz8/f38/P38GEz8efz8/Pwc/CD8/Pz8/PwU8Pz8/H38/Pz8/Pz8/BiE/Fj9NDgg/Pz8/Pz8/Pz8/Pz9+Pz8/P34/Pz8/Pz8/ez95P2w/U2ZpP2oFPz9rP3g/CD8/Pz8/P30/Pz8/fD98Pz8/PwVMP2A/Tj9GPwg/Pz8/P34/fT8/Pz8/Pz8/Pz8FPz9jPwg/Pz8/PxU3Py8/bw4IPz8/Pz8/BXU/ST9qP0A/CD8/Pz8/P34/Pz8/fj8/Pz8/PwVmPzs/ZD86Pwg/Pz8/Pz8/fz8/Pz8/Pz8/Pz8Faj9BP3U/SD8IPz8/Pz8/Pz8/Pz8/Pz8/Pz8/BXE/Qz9vP0I/CD8/Pz8/Px4/Pz9/FT9dDgg/Pz8/fT8FXz87Pwg/Pz8/Pz9+Pz9/P30/fT8/Pz8FQz8oP0U/KD8IPz8/Pz9+Bj8IP30/Pz8/BUU/KD9FPyk/CD8/Pz8/fT99Pz8/Pz8/Pz8/PwVfPzs/CD8/Pz8/PwY/CD8/Pz98PwU1PyU/NT8mPwg/Pz8/Pz8GPxU/Pz8/Pw4IPz8/Pz8/Bj8IPz8/P34/BWA/YT8IPz8/Pz8/fT8/Pz98P3w/Pz8/BUs/Tj9NP1E/CD8/Pz8/fj99Pz8/Pz8/Pz8/PwViP2I/FT8/aQ4ePz8/Pz8/P3wHQQg/Pz8/HhU/Mz8OPwc/Px58Pz99fT8/Pwc/Px4/P1AkJz8+IQc/Px58Pz99fT8/PxV9Pz8/Pw4eP2A/KgY/Px8/Pz9/fz8/fwdUIj8efT8/fX0/Pz8GIj80Px9/Pz8/Pz8/Pwc0Pz8fPz9gUAg/aD97Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8VPz8/bD8OCD9wP2Q/Pz8/Pz8/fj8/Pz9+Pz8/Pz8/P1Y/Uz9OHkZlVVAHPwhPP3U/dz9zP3I/MD8HPx85UEYoCD9UP04/Wj8/Pz8/Pz8/Pz8/Pz8/Pz8/P3E/ez8/Px4/Pz8/Bz8IPz8/Rj9CPzk/NT8/Bz8fPz8/PxU/Pz8LPw4efT8/fX0/Pz8HED8IKF9VMj9DP3w/Pz8/Pz8/Pz8/PwA/Pzg/PwdQPx4/Pz8/Pz8/fBU/bD8OCicVPz8/Px4/Pz8/Pz8/fAc/Pwg/Pz8/Hg8/KBE/Oj8HPx86PyYRPw8/CD8lP0k/YQcyHn0/P319Pz8/FX0/Pz8OCiYVWj8/Px58Pz99fT8/Pwc/CEhfUEo/Jh4PPxE/Oj8HPx86PxE/Dz8IP1E/Sz8HPz8ePz8/Pz8/P3wVHz8/Dh4NPyg0DD8HPx4PPyk/Cj8NPz8MPwc/Hw8/Lwo/FT8/His/Dj8CPyM/Bz8eIz8QPwM/LD8rPw4/Aj8jPwc/HyM/ED8DPyw/FX8/Pz8OHn0/P319Pz8/Bz8IT2lcUj8uHhU/QA4/Bz8/Hj8/Pz8/Pz98Bz8/HiJGPz8/Pz8/Bz8/Hj8/Pz8/Pz98FT8/Dh59Pz99fT8/Pwc/CFZqWV0/MD8yP1Q/b1JqVlQ/Kx4NP0AUPwc/Px4/Pz8/Pz8/fAc/Px4CP0s/Pz8/PwY/Bz8/Hj8/Pz8/Pz98Bz8/HiFKPz8/Pz8/Bz8/Hj8/Pz8/Pz98FT8/Pw4efT8/fX0/Pz8HRD8ePz8/Pz8/P3wVPwM/Dh59Pz99fT8/PwU/Pz8/Pwg/Pz8/Pz8/fj8/Pz8/Pz8/Pz8FUj9PPz8/XD8IPz8/Pz8/Pz8/Pz8/Pz8/Pz8/BT8/WD8RPxA/Px4/Pz8/Pz8/fBU/Uw4IPz8/Pz8/Pz8/P38/fz8/Pz9/Pz8/Pz8/Hmd0clsHPz8efT8/fX0/Pz8HPz8fPz8/FT8/VQooFTA/Az8OHn0/P319Pz8/B2g/Hj8/Pz8/Pz98FSw/PwooFTA/Az8OHn0/P319Pz8/Bz8/CE9pXFI/Lh4VP0AOPwc/Px4/Pz8/Pz8/fAc/Px4iRj8/Pz8/Pwc/Px4/Pz8/Pz8/fBU/Pw4eIT0iCD8HPx4KPz8/Pz8/Cz8HPx8HPy8iFT8/Pwg/cz9dPz8/Pz8/Pz8/f38/fj8/Pz8/Pz9RP0g/RB4JP0g4Fz8HQQg/tz8/Hg8/LQ4/Jj8HPx8nPywOPw8/CD8lP0Y/YQc6Hn0/P319Pz8/By4/CD8/Pz8/Pz8/PxU2Pz8/DgY/Hz8/P35/Pz9/B1RZCFE/XXtubnFxfWc/Xj9yP3g/ej8/Pz8/Pz8/Pz8/Pz8/Pz8/Px4/PwY/Mz8ffj8/Pz8/Pz8HMz9QPx4/Pz8/Pz8/fRU/Dz8/Pw4IPz8/Px4aPyAIPzM/Bz8fKD8KPyMePyM/Cj8wJj8/Pz8/BiQ/CBM/PzA/Jz9CbVhjYj8/Pz8/Pz9+Pz8/Pz8/Pz8/PxVkPz8IJD8sPz8JPz8/BT8/FT8/Aj9rDgonFVo/Pz8ePz8/Pz8/P3wHLgg/Pz8/Hg8/KBE/Oj8HPx86PyYRPw8/CD8lP0k/YQc/Px58Pz99fT8/PxVZPz8/Dh4nPw4/BT8jPwc/HyM/ED8GPyY/CD8zP1E/XT8/Pz8/Pz8/Pz8/Pz8/Pz8/P2Q/aj8/Hgg/Pw4/Bz8fDz8uCT8IP0lrVmJiPz8/Pz8/P38/fz8/Pz8/Pz8/Pz8/PxV/Pz9eDgomFTY/Pz8efD8/fX0/Pz8HPz8ISF9QSj8mHg8/ET86Pwc/Hzo/ET8PPwg/UT9LPwc/Hj8/Pz8/Pz99FT8/Dh4jSzIuB1EIPz9/Pz8eAD8/Pwc/Hz8/RT0VPz8eP1U/IQc/HyFPMBg/CD9EP1o/Wgd1HyRWPz8Iyz8/Pz8IPz8/Pz8/Pz8/P38/fz8/Pz8/dFd8WD9KP0Y/VD9mP2k/eT8/Bz8/Hj8/Pz8/Pz98B0sIPz8/PxV/Pz9hDh8/Pz9/fz8/fwY/Px9/Pz8/Pz8/PwY/PxU0Pz97Dh8/Pz8/Bnw/Hz8/Pz8/Pz8/Bmg/Pz9oPx8/Pz8/Pz8/PwZ8Px59P38/FTY/P04/Dgg/Pz8/Pz8/Pz8/Pz8FCj9YPwg/Pz8/Pz9/Pz8/P38/Pz8/Pz8FCj9YPwg/Pz8/Pz8VAz8/Pwg/Dh99f399Bnw/Hz8/Pz8/Pz8/Bmg/Pz9oPx8/Pz8/Pz8/PwZ8Px4/fz99FSM/Tj8OHj8/Pz8HPwg/Pz8/Pz8FPz9nPz9OPx8/Pz9+fj8/fgZ8Px5+P38/Bz8IPz8/Pz8/BT8/Zz8/Xz8ffj8/Pz8/Pz8GPz8WPz8OBRU/Pz8IPz8/Pz8/fT9/fj99Pz8/Pz8/BQE/Pz8BPz8/CD8/Pz8/Pz9+P34/Pz8/Pz8/PwURPz8/Pz8/Hj8/Pz8/fz99FT8/Dgg/Pz8/Pz8FPz8/Pz8/Pwg/Pz8/Pz9/P39/P34/Pz8/Pz8FPz98Pz8/eT8IPz8/Pz8/P34/Pz8/Pz8/Pz8/BT8/Pz8/Pz8IPz8/Pz8/Pz8/Pz8/Pz8/Pz8/BT8/Pz8/Pz8IPz8/Pz8/Hj8/P34VPz8OCD8/Pz8/P30/fn4/fT99Pz8/PwU/P2k/P1s/CD8/Pz8/fQY/CD9+Pz8/PwU/P1s/P2o/CH4/Pz8/fz9+P34/Pz8/Pz8/PwUdP34/CD8/Pz8/PwY/CD8/Pz9+PwU/P1o/P1o/CD8/Pz8/PwY/CD8/Pz99PxU/Pz96Pw4IPz8/P30/BSA/Pz8IPz8/Pz8/fz9+Pz98P34/Pz8/BQc/Pz8IPz8/CD8/Pz8/fz99Pz8/Pz8/Pz8/PwUiPz8/CD8/Pz8/PwY/FT8KPxo/Dh48PyELP1g/Bxc/Hn1/f319P38/BxI/Hjk/Mig/Ij81MD0/Bxc/Hn1/f319P38/BxE/H10/Pwk/Pj8VPxA/JD8OBnQ/Hz8/P35+Pz9+Bj8/H34/Pz8/Pz8/B3Q/Cj8ePz8/Pz9/P30VPz8/Pw4IP2o/Sj8/Pz8/Pz99P39/P30/Pz8/Pz9FP0U/Kx4iUEM7Bz8IQT9gP2szP2k8P1I/IT8HPx8jOywWPwg/LT9KP0s/Pz8/Pz8/Pz8/Pz8/Pz8/Pz9cP3g/Px4/Pz8/Bz8IPz8/ZT86Pz82P0c/Pwc/HwU/Pxs/FT8/Pw4eCT9QNCYHPx8tUD8TPwc/Pz8VPz8/H31/f30GPz8IPzU/Rj9hP2o/dz8/Bz8ICT8/Pz8KPwU/P1s/CD8/Pz8/Pz8/Pz8/Pz8/Pz8/PwU/P2s/B3k/Pz8ePz8/Pz9/P30VPz8OCD8/Pz8/P3w/f38/fD8/Pz8/PwU/Bz8IVFtAbzk/Bz8eQT8iPxI/QT9BPyA/ED9BPwc/H0E/Ij8SP0E/CD9Dc0thWQUnCT8VaT8eaD89Px8/Uz8HPx5TPz8/IT9oP2g/PT8fP1M/Bz8IPz8/PwU/Owg/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8FQz8IPz8/FX88P34/Dh4WP0czIwc/HwM/UT8SPwdaPz8VAT8/H31/f30GeD8eLj8hGz8HPx8nPxM/Jj8HUT8/Px4/Pz8/P38/fRU/Pw4eQT8gPxA/QT8HPx5BPyI/Ej9BP0E/ID8QP0E/Bz8fQT8iPxI/QT8VPz8eaD89Px8/Uz8HPx5TPz8/IT9oP2g/PT8fP1M/Bz8fUz8/PyE/aD8Vfzw/fj8OH31/f30GPwg/Pz8/Pz8FPz9sPz8/Hn0/P319Pz8/Byg/Hz8/Pz8GPwg/Pz8/Pz8FPz91Pz8/Hj8/Pz8/Pz99FT9CPw4ffX9/fQY/CD8/Pz8/PwUmPz8/Jj8/Pwg/Pz8/Pz8GPx59P38/ByM/Hj8/Pz8/fz99BT8/Pwo/Pz8IPz8/Pz8/Pz8/Pz8/BQo/Pz8/Px4/Pz8/Pz8/fRU/Pz8OHn1/f319P38/Bgo/Gz8ffj8/Pz8/Pz8GNT8eP38/fRU/Pw4efX9/fX0/fz8FSj8/XD9OPwg/Pz8/Pz8/fj9+Pz8/Pz8/Pz8FPz8/Pz8IPz8/Pz8/Pz8/Pz8/Pz8/Pz8/BT8/Pz9EP0I/MD8/Hj8/Pz8/fz99FT8/Dgg/Wz9IPz8/Pz8/P30/f38/fT8/Pz8/P2I/XT8/HjVKSQ4/B1o/Hn1/f319P38/B1Y/CD8/Pz8/Pz8/P8sVPz8/SA4efX9/fX0/fz8HJD8ePz8/Pz9/P30VPwM/Pw4efX9/fX0/fz8HPz9UPz8efX9/fX0/fz8HJD8ePz8/Pz9/P30HPz9UPz8ePz8/Pz9/P30VPyQ/Dh5xPzc/Fz9ZPwc/H1E/QT8dP2U/CD8iP0Y/Sj8/Pz8/Pz8/Pz8/Pz8/Pz8/P2E/bj8/Hj4/JD8LPz0/Bz8fST8bPwU/Tz8IPzJmOGBYBl0/bj8fPz8/fn4/P34GPz8efT9/Pwd5Pwg/Pz8/Pz8/Pz8Vfz0/PD8OH31/f30GUz8ffj8/Pz8/Pz8GOT8/Pww/H34/Pz8/Pz8/Bww/Pz8ePz8/Pz9/P30VPz8OHj9/P30HHD8ffX9/fQZYPx9+Pz8/Pz8/PwY+Pz8/ET8ffj8/Pz8/Pz8GET8/P0M/H34/Pz8/Pz8/Bl0/FhY/Pw4eVz8ZPw8/Oz8HPx86Pxw/Dz9XPwdJPz8VBj8/H31/f30GYz8ecD8rPyw/WT8HPx9ZPy0/LD9wPwZjPx4/fz99FT86Pw4eXD8zPyg/XT8HPx9aPzg/KD9ePwg/CD8/Qj9HPz8/Pz8/Pz8/Pz8/Pz8/Pz8/Vj9lPz8ePD8dPxM/RD8HPx9FPx4/FT87Pwg/LGlITEk/Pz8/Pz8/fj9/Pz8/Pz8/Pz8/Pz8JPxV/OT8OPw4eDD9UPzMHPx81WT8ePwc/Pz8/FT8/ez8eIlhALgc/Hz5XPwQ/Bz8/Pz8VPz8/H31/f30GPz8IPzw/Sz9kP24/ez8/Bz8IPz8/Pz83P0E/Pwc/Hwk/Pys/Bj8/Hj9/P30VPz8OBSk/TD8pP00/FXU/LT8IPz8/Pz8/BRw/Pz8IfD8/Pz95Bj8IP3k/Pz8/BRo/Pz8IPz8/Pz8/Pz8/Pz8/Pz8/Pz8/BUg/PzE/ST8IPz8/Pz8/Hj8/P38V3UI/Dh8tLDUpPE8/Pz8/PwQ/P1Q9FT8/Vh8/P1k/Uj8/Pz8/Wz9VPz8/Pz9NP1M/Zz8/Pz8/CD9nP1I/Pz8/Pz8fP0M/ISM/IQ0/BD8IPzo/Xj90BVA/CHw/Pz8/fj97Pz8/PwVWPz8IPz8/Pz8/Hz8/alJFTUElP0s/ST9AP3o/ez9LP0E/cz90P0g/Pz8/Pwg/KXVEYUE/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8VNj8/PwA/DgogFQ8/awg/Pz8/fz8FFT8/CH4/Pz8/fD8EP1Q+Kj8HPx85Rj8/CD8/Pz8/Pz8/Pz8/Pz8/fj8/Pz8/Pz9MVl5HPyYeGD82Pwc/CBA/Pz8/CD8FAz8/CD8/Pz8/PxVHPz8/OQ4IPz8/Pz8/BWw/ND8IP34/Pz8/Bz8IPz8/Pz8/BWw/ND8IPz8/Pz8/Pz8/P34/Pz8/Pz8/BVw/Gz9ePxs/CD8/Pz8/Px9+Pz9+FT8/Az8/DgolBHU/CiUVSz8/Dgg/Pz8/Pz8FbD80Pwg/Pz8/Pz8HPwg/Pz8/P34FbD80Pwg/Pz8/Pz8/fj8/Pz8/Pz8/Pz8FXD8bP14/Gz8IPz8/Pz8/Hz8/Pz8VPz8/Pw4KJBU/P28KIBV1Pww/DgogBD0/CiAVdT8MPw4eCz8xPzMHPx4oPD8IPwc/Pz8HPx8/PzwDPxU/Pz8IP2k/YD8IPz8/Pz8/fT9/Pz99Pz8/Pz8/P1U/Vj9PPyE/Kz8oZj8/Pz8/Aj8eIT8tPww/Bz8fFT8hJyY/CD9AP04/YT9VP2kgPz8HPx9wPzI/Dj83PxV/Pz8/Dh4VP0Y+PAc/HjRMPwY/Bj8/Pwc/Hz8/PhU/BD8/HihRODUHPx48Uj8/Pz8/Pwc/Hz8/OCgEGz8eJz86BT8IPwc/CDk/TUhuM28/Vz84Pwc/HgE/QQc/DT8NPwc/AT8HPwg/Pz8/PzM/SD8/Bz8fCD8FPyc/FT8/Pw4IPz8/Pz8/BT8/Pz8/FT8fPz8/fX0/P30GOj8efT8/Pwg/Pz8/Pz8FFz8/CD8/Pz8/Px4/Pz99FT89P24OHgU/OUEoBz8eK0M/Az8HPz8/Bz8fPz82BT8VPz8IP28/YT9RP0U/JT8/Bz8fZz88PwM/Qj8IP0E/Uj9TCD8/Pz8/Pz8/Pz8/Pz8/Pz8/P2I/dT8/PyI/KT9qPz9HY01KPwY/HhM/Bj8RPwc/Hxg/Px4/FX8/Pz8OCD9eP1Q/Pz8/Pz8/fz9/Pz99Pz8/Pz/GUD9HP0UeAz9APiYHPx8oSD8FPwg/Pz8/Pz8/Pz8/Pz8/fj98PwU/P3oIeD8/fz99Bj8/H30/Pz8/Pz8/BT8/Pz8/CHVee14/Sh4bPyIRPwc/HxU/PyE/FX8/Pz8OBTI/PzI/PxU/PwYHPx4/Pz97CD8/Pz8/PwVxPxY/CD8/Pz8/fx56P38/BmQ/LB9/Pz8/Pz8/Pwc/Kj8ePz8/Pz8/P30VP1E/Pw4IPwE/Wz9HPz8/Pz8/P30/f38/fT8/Pz8/P1Q/SD8zHi1MPC8HPx8pVT8SPwY/Hj8/P34IPz8/Pz8/BT8/ej8/Hz8/P319Pz99BiI/Hn4/Pz8IPz8/Pz8/BT8/fD8IPxk/Bz8UPz8HPx8OPz8NPxV/Pz8/Dgg/Pz8/Pz8FeT8/PwgiCD9PZEE/CDA/UD8/Pz8/Pz8/Pz8/Pz8/Pz9+Pz8/Pz8/PzVQV0s/Cj8eCz8yAT8HPwg/Pz8EPw8/BVY/aj8/Cz8ffT8/Pz8/Pz8GSD8ePz8/fRU/P3EOBT8GPwg/Pz8/Pz8/Pz8/fz9/Pz8/Pz8FXg4/CD8/Pz8/PwY/Hns/Pz8HKD8ePz8/Pz9/P30VP0c/Pz8OHiU/Kz8xNj8HPx43Pyw/JT8lPyo/Nz8HPx82Py0/LyU/FT8/HkY/Oz8DP1U/Bz8eVT89PwU/Rj9GPzs/Az9VPwc/H1U/PT8FP0Y/FX8/Dgg/Pz8/Pz8FCj9YPwg/Pz8/Pz8/fz8/Pz8/Pz8/Pz8FCj9YPwg/Pz8/Pz8ePz8/fxUDPz8IPw4KIBU/Pw4fP34/fHx+fnwGcD8ffD9+Pz8/Pz8GcD8VP2Q/DgokFTE/DgZZPx8/Pz9+fj8/fgdZP1Y/Hn0/P319Pz8/BlY/WT8ffj8/Pz8/Pz8HWT9WPx4/Pz8/Pz8/fRUaPz8/Pw4FPz8IPz8/Pz8/Pz8/Pz8/Pz8/Pz8/BVokWj8IPz8/Pz8/Pz8/Pz8/Pz8/Pz8/BT8wAT8/CH8/Pz8/fz9/Pz8/PwUBPz9NMAg/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8FPz8kCD8/Pz8/Pz8/Pz8/Pz8/Pz8/PwVNPwE/Pwg/Pz8/Pz8/Pz8/fz8VPD9XP04/Dgg/Pz8/Pz8/Pz8/Pz8rKz8VPzY4Pz84Pz8VPysrPwg/Pz8/Pz8/Pz8/Pz8/Pz8/Pz0/JT8oRz8/Rz8/JT8/PT8/Pz8/Pz8VHz9OPw4IPz8/Pz8/KD0/JT9HPz9HPz8lPygoPT8IPz8/Pz8/Pz8/Pz8/Pz8/Pz8rPxU/OD8/OD8/FT82Pys/Pz8/Pz8/Hz8/Pz8VHz8/Tj8OCiEVYT8OCD89YUhHUQVqP2M/CD8DPz8/Bz8fPz9HKxUKP3cIaydaWEk/Bz8eTVs/Pz8/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AG4AIAB5AGEAbQAgAHUAbwB5ACAALABzAHQAcwBpAHgAZQAgAHQAbgBlAG0AZQBlAHIAZwBhACAAaABjAHUAcwAgAG8AbgAgAGYASQAgAC4AbwBDACAAJgAgAHIAZQBsAGYAZQBvAEgAIABkAG4AYQAgAHUAbwB5ACAAbgBlAGUAdwB0AGUAYgAgAHMAdABzAGkAeABlACAAdABhAGgAdAAgAHQAbgBlAG0AZQBlAHIAZwBhACAAZQBjAGkAdgByAGUAUwAgAGYAbwAgAHMAbQByAGUAVAAgAGUAaAB0ACAAbwB0ACAAdABjAGUAagBiAHUAcwAgAHMAaQAgAGUAcgBhAHcAdABmAG8AcwAgAHMAaQBoAHQAIABlAHMAdQAgAG8AdAAgAHQAaABnAGkAcgAgAHIAdQBvAFkAIAAuAG4AbwBpAHQAYQBjAG8AbAAgAHkAbgBhACAAbQBvAHIAZgAgAHQAaQAgAHQAcwBvAGgAIAByAG8AIAAsAHIAZQB0AHUAcABtAG8AYwAgAHkAbgBhACAAbgBvAHAAdQAgAHQAaQAgAGwAbABhAHQAcwBuAGkAIAByAG8AIAAsAGUAcgBhAHcAdABmAG8AcwAgAHMAaQBoAHQAIABkAGEAbwBsAG4AdwBvAGQAIAByAG8AIAAsAGUAdAB1AGIAaQByAHQAcwBpAGQAIAAsAHkAZgBpAGQAbwBtACAALAB5AHAAbwBjACAAdABvAG4AIAB5AGEAbQAgAHUAbwBZACAALgBvAEMAIAAmACAAcgBlAGwAZgBlAG8ASAAgAGYAbwAgAHkAdAByAGUAcABvAHIAcAAgAGUAaAB0ACAAcwBpACAAZQByAGEAdwB0AGYAbwBzACAAcwBpAGgAVAAuAG8AQwAgACYAIAByAGUAbABmAGUAbwBIAC4AcwBuAG8AaQB0AGMAaQBkAHMAaQByAHUAagAgAG4AaQBhAHQAcgBlAGMAIABuAGkAIABkAGUAcgBlAHQAcwBpAGcAZQByACAAZQBiACAAeQBhAG0AIABoAGMAaQBoAHcAIAAsAC4AbwBDACAAJgAgAHIAZQBsAGYAZQBvAEgAIABmAG8AIABrAHIAYQBtAGUAZABhAHIAdAAgAGEAIABzAGkAIABkAGUAZABuAHUAbwBSACAAbQBhAGgAdABvAEcAdABuAG8ARgAxADAAMgAu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)); font-weight:300; font-style:normal; } \ No newline at end of file diff --git a/docs/static/fonts/332720/E83A474C5EE950C81.css b/docs/static/fonts/332720/E83A474C5EE950C81.css deleted file mode 100644 index 1eb5423b53..0000000000 --- a/docs/static/fonts/332720/E83A474C5EE950C81.css +++ /dev/null @@ -1,19 +0,0 @@ - -/* - Copyright (C) 2011-2015 Hoefler & Co. - This software is the property of Hoefler & Co. (H&Co). - Your right to access and use this software is subject to the - applicable License Agreement, or Terms of Service, that exists - between you and H&Co. If no such agreement exists, you may not - access or use this software for any purpose. - This software may only be hosted at the locations specified in - the applicable License Agreement or Terms of Service, and only - for the purposes expressly set forth therein. You may not copy, - modify, convert, create derivative works from or distribute this - software in any way, or make it accessible to any third party, - without first obtaining the written permission of H&Co. - For more information, please visit us at http://typography.com. - 171247-88474-20150623 -*/ - -@font-face{ font-family: "Gotham Rounded A"; src: url(data:application/x-font-woff;base64,S0EpP18/Wj89PDM/GT8/PzA/H3p5Jz8/VD8/Wm8/Cx1kP2w/Pz8PP3cOCD9DIz8/XQJyCj9ZPwUzQz9IPz98NEtxIz8/LUQ/Pz8/TyE/Pz8zPz8yYj8/Pxo/aj9OH1g/PT8fJUscPyE/azw/Zz8hP04/LkV+Rz95T1R4EFM/M3k/YD9Waxw/P0w/P2A/ATckem0/P0NNCz8/Ex5LOj8PA1JiPzl1Dj8ZPT8/Pz4/Zj8VPz8MPzA/GiE/Pz8/Ez8BFj8/NGohPz8UFz0/Kz9APz9BP30/Pw0/Pz8lPxM/Pz8EAz8/OB0/P0UqG1o9Iz8/GHw/dXZbSxk/PwZLWgFQGmg/KTRkFHk/Pz86Pz9gEz9tTg8/Lj9ZPz8Cfj8lAD8/aC1OPxI/Pz9zVT9wFUA/Lj8jPxE/cz9PPw8rU2I/DhM/VT0/TD8/acg/NT48aD9GP0c/Pz91Py0/SXU/aT9gP1RVP0EfQT9fGHQ5XAM/Pz9UP0Q/Kj9CMDkkaD8/Py4/bD8/Pz8/Jj9FPz8/P2ceYj8/Pz9sPxY/P1BJUWw/Rj8/aT8/PykIMT9FPz8/LxVzbT9VPzI/Pz8BGmQ/RVk/XnR7A3VvLz8/fT8/P2o/SRc/P20JA2kNPz8/cT8hWlg/HWsVHA4QP0A/ZD0/AE0JPxMwMD47FT8/EDA/cj9VPz94MgA/Al0APwA9ACoCOgBdA1MAZQIzAD8BXQA/AToAPwI8AD8CSQA/AmgAFgNvABIBaAA/AmgAPwI1AD8DQgA/AjcAdgJAAD8CPABdAjcAYgIsAE4CHgBPAUEAPwI9AHgCXQA/AAAALAEAAD8BCgA/PwEAAQAAAABNAGgFABg/AWYgKUIEYGJgEAYJYgM/YGBkYGM/eAAAADk/Hj8PPz8/OSUzP1IjBg4/TjlKPz9/PwUgP2hhIj8/Tj8/UDg/VFI/Hz81Pz8fPyNRPz9RP1A/Pz8lChk/ZS0/PyJFCg5rQj8/T3UYKC4pPz8/Cz9GPzc/Pz8mPw9NRGY/Bz8/XT8kPz8/D3N7dj8/Wj8+Pz8qPz9tJT9hSj9kfT8/Pz9vRD8/CBwkW2k/PyF6bHY/Pz8/PyE/YRAwDD8/PxYtBFRoPwphUCk/fHgGPwE/PQIgPz8/bSFLPz8/PxY0SgNSPz10N1MHPzM0UFY/Wz8JRD9wUT9DPzE/Pz82Lj8/PxI1cT8/LCI/Pz8/P0M/Pz9FMT8/Pz9FP1phPx9JKD8XJj8JP2ozND8/PxJzQD8/MD8/KD8/TQZRET9HbxNlLVs/Pz8/MD9cP2lqP0M/Pwp3bD8/V3E/Nj9oCz8wW3A/P0g/Py8/Ye92Pz9nPz8/Pz9hbz8/OiwZYT81Pz9LdT9NYRQ/ZT8/P10/Gj8/aT8/ZD92Pz8/Bz8RPz9LeT8/bj87QEY/Pz8/C2c/HjwzOj8/Pz9FAEo/XGw/Pyk/aT9oPz9kPy1ENCIQP2UBP00/P3QAPz8Ibj92G3sNUmRjPz8TfCk/ZD8oVANOPz8WIT8/bz8NP0o/P1U/QzE/Py4VZWQ0NRE/Fz9uPzYCP2c/Pz8vSD9LJl0FPys/bz8/Ch4/Pz8tPwY/P2A/Pz8dPz8IPz8/PwRtOD8wCT9XHDMmPwFiPz90Pz8iWj8JPwE/YiNDPz9pDz9AUz9mPz8/PQIlPz8pUHY/Pz8KP0diP1J0PyAWPzVDWT8/JC9/P2VJOVY/QlRoPz8/VQ1ETD8NMD9GaWA/Oj9hPTh6P3hZRT8qNWw/P3Q/NT9RXWl1Pz9wPz8pZj9VRj9zP1k/Fz87Pz8/KSVXQmQ/P20/Pygkfz8nPz8TLT8/Z0A/Mho/Pz8/P1Y/RBk/GDY/Pz8nPz8VPwA/VRE/Lyg/dU4/PxM/Pz8/Pz8/Pz8/ST9wDEYST3s/KT9lPz8/PTE/FnA/P0g/PwMuLmQ/WRkuPwASPz8/Vj8/Dz8/Pz8+fAA/eD8nRV0/Hwwtfj8DPwg2Pww/KD8/P2E/P1woVz8/WHc/Pz8/Fj8/LD9JJT8uPz8zXj9HYTM/KEk5P3lfNxA8Pz9HPz8/BT8/UHQ/Pz82fRRaTT8/XT8/PwdOEz8/KW5hPz96PyU/CD8EPyw/VT9dVT8/Pz8/aj9RP1IhC0lkEz8xQAE/Iy1ZMz8/Pz8iP0YaJH0/P3ChIT8/P2A/dz8/ORM/Pzk/PxZSUjomPz8/XEQ/Pxs/dihtHD8sPz8fTz8/P3teRwI/EFgJPz9tPx8/P14/ED8TPz4/Tj8/ATU/Gz9LP2gnPz0PRmQ/Pz8QPz9GPxQzSXovNgsMPiNeXz8/GWlzDD8/Pzs/Pz8/JXsmP2s/Pz8/Px8xS2Q/TD8/Oj9ufgc/Pz8eJz8vPz9COBY/S2g/Pz8/Pz8/Xj8/YTM/Vz8/P3VfP18IPxM/fGE/Az8hPw0/V090Pz99Lj8/Oj9QPz9XCD9fPz8/TBk5T3QZPzIKPz94Pz8/bk8QPz9xPxVfP1M/HxIXAj1SPyMjP28pPxR9P1IIPz88Oj8tPz8/UU8/fj8kXCM/dj8GUiI/FD8/Pz8/P2J5NyBNXzc/P1g/bj8/Pz8/HT8/Pz8OPz8/IT8/Pz8/MHg/SR0MPzdzRlo4H3o/Pz9IP3A/AgdKHT8/bz8/ET8NFz8/Pw8/GD9yET8MRT0/ID8/P0lbFWIfAz8/Pz8/Iz9ZAhA/Mz9JCSMJPz8/JD8CIWI/WA4/D1kNNUlKTT95Kj8/Ej8UPz8/ZisodD8/Pw8/PD4/P3Q/CGQ/Pys5Pz9+XD9CKz8ceD8/P3Y/JzkOKT8tP2FfP20/Pz8RTHk/ETo/Pz8/Pz8/Pz8/Xj8/Cz8/PyI7P04/Pz8/Xz8cPz8/PwUtDgUsPz9+P08/Pz8/PwYMEC5iPzs/eD81P3dFPz8/Pz8lPyc/Gw8Hez8/PRxMVlY/P3s7Pz8/OD8LPz97Py8/PxI/Pz9ESD95PUdGJDk/FkFeOnhTPz8HP1cHPz8/bw0/Pz8/P0ojJS4MPz8/FD8/PwdNPwoHaD8iKz8/P09GDD8/ez8/cH4jP385P1U/P3kAPww/Pz9BP1U/Pwk/P0w/C3oKPz8/Wj8WPGoKIT8sCwQ/dDAfPx2ZXwkmRj8/Pz9Tdz8/Pz8/Jz8/Uz8nSz8/P1M/Pz8lO3k/Yz99Pz9vP3kqP2wNXD8/ElVfPz9FPyl0PzlJPzZTPz8IXEVLPxw/PyI9QD9KPz8/GT8/LW8/Pz8/Jz8/Hh9iPz9XPz9BED8/KzdDPw8/Pz8wPz8/dT9pPz8wPz8/JFw/Nz8nZUlfPz4/eH9OCj8/R30/cWt7P1E/P1dRdFEZMDk/mmE/cj8/Pz8/Pz9VP3Q/Pz8nPz8EPx52J10/Pz8/PxF5GEc/Pz8BYT87fRU/Pz8KTj8/dFx5Pzw/Tz8/Lz8/P4M/IBQ/Pz8/Pz8zPT8/Kj8VP1Q/P0c/QCo/PzA4LRJyPz9zUD9iJT8qeD8/BwM/Dh4FcRdVPz8/P3M/Pz8/NyOdZT9HPxlyP1lqGT8/Pz8/Zz8/Pz8/GzUSPz8/Pz8/TD9FID8/Iz9TP09mEAF8Pz8APxw/Pz9MPz8/bH0/Px4/JEdUcF8nPT8/GnxuPzY/X20sNnFWPz8/dDg/P1g/Pz8uGj9+Onw/BT8eZ1k/PxspPwA5Pz8gREpCWj8/f2oBOD9ofD8/Pz99Yj8/HHM/Pzw/Pz85FWRsPz8GPz8/Pz8/PxQ/PzZQP200PzZGPzs/bT8/I3wBP0c/Pz8/Pjo/P1k/CD9NZD8/Pz9EcD9LPz8/CF0/PwM4WT9kcH1vWEw/QUhZP2Z0Ggo/P0YmP0c/AyRQMhM/MF4/ET8/HxcEPFiLPwEDPz8/Pz8uWj8TPyZAPwM/Pz8vcwg/Sj8/MB0/TBA/BSQ/GylvPz8/PwhcYxdpP2w/PxM/Pz9zBD8hVj94LT9MPz8/Pz8/PyRdPww/HT8/Pz9PJD9jPz8/PzU/RGs/Pz8/Jz9iPyVMPw4/P09ceT8/XFQ/Zg1wFBI/Cj8/dz8/nic/eRE/Xj96PwA/Pxw/P1BlPz9sPHi7GD97Pj8EPz8VPyk/KGdnTD9ePzo/Pzw/P1g/Pz8/QycDPz9JSxk/cj8/P38/Xz8vPz8/eD8uBj8DP3k/eD8/P2Q/PzZQP1UZOT8/dz8/UxFOP2A/ET8/Pz8/Zz8/aj8/eRA/HT8LP6hGDTA/Fz8/PxA/fRs/P30XPwgfXz8UPz8/P25cP2BcPz8/Pwo/Pz8FChAuQT8JPy5sLT8/LT9bbT9ZID8/Ij9fIz85H1gWPwQ/Pz9hPyA/GT8nfAJBPz8/Pz8jPGQ/AVo/P2FvP2ZAPxEuTj8fIz8/Gz94P3Y/PBgeDz8DPzoxPwxFXhw/fz8zbgo/Pz9gWT8/bFA/TD8/Pz9WWF4/FgguPxc/Pz8/Nj0ha3MaBT9jPz8/PzIWYCw/UyZmZD9xPzs/KmQ/UwtzM3MTcxhmRj8GP3o/UD8/Ux8/Pz9bPz8/Oj9dPz8aKw0/Pz9LS1xuMj8/NTZWS2MNPyU/Pz8/ZD8/G2pLez8/PyY/Pz8yUV1eUlQ/WD8/Pz8/dW4/PlY/PxQVFD8eLx4/Hxhjbz8MRz8fbz87fz8gIj94Pzs/W3s/W3s/YT86P3I/Pz9rDTU/FBQUP1xTAW5zPz9zPz0/ez8/Pz9+Wj8/fj93Pz9qP1c/IT8APz8IP3lUPz8VWlM/Pzc/Pz8/Pz0/PzE/bHkNJDQlKQUqKH4/PzwkURA/PDBQQUM/JAwEPz8/PyI/P2Y8Pz8UfAtWTT94AD8BPywAAD8YPxlbPz8AZmBjP3gAAD8/RT9LPz8ueSU/FF57ClE/Ljc/bT9vP0A/Cz8/Pz8/bz94Pzc/Pz9vP3g/PzscPz8/PzM7Pz9rP39hP20pEz9jPyc/PwiVJT8/Pz8/P3RmP0I/P2Y/Pj99ZjU/PxF8Pz9KZT9WZD9eZBZJZT9VZD9dZDZUST9MSz9LZHZfZD9vPz9QPz9EPz9PP38/P3s/Pz8jXHQnUnQ/RnUXRXVGPz9tPz9/X3Q/ZH99Pw1/CD8NNz9LPyQ/P0M/Pz9cPz8HGj88fgh+DRwUUT89Pz9hPzIOAT8xP1s/Pz8/Pz8/Pz9WP3wtPz82ej9ZKwVnLGU/Pww/H0M/dD8UP34uP9gIYwg/CEE/Vz94PwE/Pz8NQTxjPzwzP0h1BGswET88P00/OGZoCUc/Bz8vcz8/L3M/Hz9zP3E/P047Pz9zPy1Faz8SPz9FQwYhP0VBEj8iIn4hEXA/Hz8/JEE/P0ZDKz8haD8LPz9EFD9JPz8/XCA/P0ccPnE/P2c/FFE/Sz8/P3gAJmo/P28/Pz8/P28fPw8/P0Q/Pz8/P3c/P30NCT8/Pz8/PT8/Pz8/P3s/ST9cPz8/aXVUPD8/P2M/P0s/Pz8/PT8/Pz8/bk5/eWNdPz97ED8/Pz9zPxk/P34/Pz9PJQY/Pz8/cUA/Oz8/Nz8/Pz9PFS5ueT8cKxQKeS5HJT9uP1NKP3I/Pz8SIz9OP3g/Pz8SPz9bPz8/Pw0/Vz8/Pyg/Wj8/bj87VVVwWj8hO1NWez8TVT8/Pz8yP3koPz88E1c/Dz9KPz87Dz8/Pz8/KGo/DD8/eT8/ED8/P3kePyM/Zj9oST9NP1J3GVcrPz8/Pz8/Yj8/Iz8/cz8/Pz81C1Y/UHM/MT8/PwFRPz9PPz8/Qz8/Xz9iOQw/Pz9yPz8/Oj8KZEM/Mz92Bi4/Tj8pPz9HP1s/GmIFP1lPF1o/P3M/FT8nPyI/EUZ7Bj8APwQ/Qj8/elg/Yz8/PwE/DD8/QFY/Kz8/PUAFHgZHMT8/XT8EXD8AaHE/HQ4/AT8/Mz8NPz9oSj9CPz9lPxY/Fz8/cE8/Sz8/Pz9mPzk/fwY/Pz9kRT8/Pz8ZPzg/Pz8XSndfF30/Pz8/I0UKP3QAfDs/Pz8/fT8jPz96CSw/PzQlDD8/Iz8/Pz8/Pz8DPz81Fz8SIiE/P2dIPyM/P29uP0c/P1JlP0Q/Tz9tY2UvYT8/SBE/Kz8XXD9eQz9DBGg/Pz0/Sz9lVT9XPz8nGD8/Xz97P2ZQYD9MP1Q/P0A/IG9QPyxGQyo/SjY5CVA/LmVLPz8WPyk/Pz9cPz8UDD8/LUI/LVs/PyN+Z2k/P0Q/Pz8ZHT8/Lj8JP1I/aVk/NmU/HD8rEiJkP2FZJW8BGj8ZaD80Pz8/P21VPz9JPwI1P2Q/P0U/Jj9FbTI/XiY/PzpRPz8/Pz8cP0o/UEE/Pz9dP1EFPyURSTQ/Pz9YPz9MPz8/UT8/YmcqRT8kP0xbY1FoPyFzSj8jI1hSED8/FSI/Pz8VMj8/Pz8/Yz8/Pz8/Eik/Pz8/ME8/Pz9xP34/Pz97Pz8wcHA/P0E/PwQcE0g/P05TFit4Pz92Tz8XTj8/HmRsej8/Pz9NPz8/Pz8cV2IyPz9WPw9+Pz9vXj8SPR4eK2M/PzM/SD9xPxo/Pz8/bT8uPy1WPz8/Pyc/YD8/Pz8/fD8/NRs/Pz8/P3U/Pz8/Gj8/P29aLT8/Vj8/P3lfWm8/ej9bd0I/en8/Pz9xP35vPwY/P0n4PzU/DTV7Pz9mPz93OWo/Pz98eD8/dj98emxuP1w/Gj8/Pz8/Pz81Pz8/Wz8/Py0/WT9VPz86Mz83Hj8aPz8KPz99Bj9bP18+Pw1OP2g9ERA7Nz8/Z2cfaQg/Aj8/TFU/Pyk/Pw8/eic/Hj8/Px4/Pwg/Llg/Ij9EP0VxPz9jP3M/A1FTPz8oPz9KP0YGP2BRTH0/OD8/clkdEEY/b01UP3gAfw8/PwAIP0AKDD0/Pz8cP258Px8MAz8JPwU/WT9APz8gfD81D3xgPxgYAz8YGAsCQGI/MRgyPxk/Az8/Pz8/P2FgZWBhP2U/YmBjP3gAABsAAFAAAAAAAGkDP1gAGkA/DD8MPwIAYV5IAF8/PmBgZGBjP3gAAD8JPzMACiQJPz8/IAVmfD8FPz8IP0w6Cz8RQBc/bgZXPz88aD8/Wz9wZGBgYGRgYz94MgA/PyAAAAATAAAAPwcAAHRzb3AEMzUoPwsAAD8EAAA/AQAAZW1hbgBQGwAGAAAABgAAAFwBAABweGFtPwY/PWwAAABsAAAASBQAAHh0bWgAA2EHJAAAAB0AAAA8AQAAYWVoaD9HFgM2AAAAMgAAAAgBAABkYWVoCwAAAAgAAAAIAAAAQBQAAHBzYWcCPz86AwAAPwEAADwGAABwYW1jSyU/VWAAAABPAAAAZAEAADIvU08EAEgAIAAAAB0AAAAgFAAARkVER2M/P09vDgAANQwAAD8HAAAgRkZDAAAAAAAAAAA/BgAAJgIAAD8UAAAAAAEAPx8AAAAACwA/FgAAT1RUT0ZGT3c=))); font-weight:300; font-style:normal; } @font-face{ font-family: "Gotham Rounded B"; src: url(data:application/x-font-woff;base64,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); font-weight:300; font-style:normal; } \ No newline at end of file diff --git a/docs/static/fonts/332720/EA2EC948C7D7C063B.css b/docs/static/fonts/332720/EA2EC948C7D7C063B.css deleted file mode 100644 index 85e2bd607b..0000000000 --- a/docs/static/fonts/332720/EA2EC948C7D7C063B.css +++ /dev/null @@ -1,19 +0,0 @@ - -/* - Copyright (C) 2011-2015 Hoefler & Co. - This software is the property of Hoefler & Co. (H&Co). - Your right to access and use this software is subject to the - applicable License Agreement, or Terms of Service, that exists - between you and H&Co. If no such agreement exists, you may not - access or use this software for any purpose. - This software may only be hosted at the locations specified in - the applicable License Agreement or Terms of Service, and only - for the purposes expressly set forth therein. You may not copy, - modify, convert, create derivative works from or distribute this - software in any way, or make it accessible to any third party, - without first obtaining the written permission of H&Co. - For more information, please visit us at http://typography.com. - 171247-88474-20150623 -*/ - -@font-face{ font-family: "Gotham Rounded A"; src: url(data:font/truetype;base64,AAEAAAASAQAABAAgR0RFRgCSAAQAAFooAAAAIEdQT1O4zqMDAABaSAAAHAJHU1VC6cktSgAAdkwAAACAT1MvMlZTVhkAAAGoAAAAYGNtYXAYs4kcAAADpAAABJBjdnQgAFkERQAACfgAAAAWZnBnbZJB2voAAAg0AAABYWdhc3AAAAALAABaIAAAAAhnbHlmoNnAmwAACtwAAEKkaGRteAAAAGgAAAOcAAAACGhlYWQDhpSLAAABLAAAADZoaGVhB74DrAAAAWQAAAAkaG10eNgOGP8AAAIIAAABlGxvY2HxowM+AAAKEAAAAMxtYXhwAo8CnwAAAYgAAAAgbmFtZQpE/BQAAE2AAAALo3Bvc3RZVVtEAABZJAAAAPlwcmVwQHBdfwAACZgAAABeAAEAAAABTQ5DHEioXw889QAfA+gAAAAA0CwCHwAAAADQLAIf/+j/OAQTAyIAAAAIAAIAAAAAAAAAAQAAA8D/EAAABE7/6P/oBBMAAQAAAAAAAAAAAAAAAAAAAGUAAQAAAGUCCQAfAAAAAAABAAAAAAAKAAACAACVAAAAAAADAioBLAAFAAQCvAKKAAAAjAK8AooAAAHdADIA+gAAAAAAAAAAAAAAAKAAAH9AAABKAAAAAAAAAABIJkNvAAAAICEiAyD/OADIA8AA8AAAAJsAAAAAAf4CvAAAACAAAgH0AAAAAAAAASwAAAEsAAABmgBGArwALQM4ADcCuAAxAOYARgGuAEcBrgA8Aa4ATAJsAEAA5gA2AZgAQgDmAFIB9P/6ApgALwJLAEAA8ABXAPAAOwJsADwCbABPAmwAWQIWACUDFgA4AtIAaALiAEkDDgBoApAAaAMQAEkCJQAqAssAaAJrAGgDZABoA1IASQKcAGgDUgBJAtMAaAKAAEECiAAyAvgAXQLuADgETgA8AtIASQLMADYCsABHAa4AYgH0AAkBrgA3Alj/6AI+ADMClABdAjsAOgJIADoBagAtApQAPAJlAF0A+QBeAPn/+wIwAF0A+QBkA7cAXQJlAF0CgAA6ApQAXQKUADwBkAAqAkYANQI6AEMCTAA0AeAANwEeAHkB4AA1AkUAPgKEAEICrgA1Az4ANQGGADoCAwA3AaAAIgHCAEoA5gBSAYYALwIDAEQCFgA0AhAAQgOCAEIA5gBNAOYAOwDmADYBmgBNAZoAOwGaADYB1gBvAqgAUgE3ADcBNwBEAtAANwKyABYCtgAyAAAAAAAAAGgAAAADAAAAAwAAABwAAQAAAAADigADAAEAAAAcAAQDbgAAAKoAgAAGACoAIAAjAC8ANAA3AD8ARABHAE0AXQBfAGMAcQB0AHYAeQB9AKMApQCrAK4AsAC3ALsAxQDHANYA3QDlAO8A9gD4AP0BBwEOARABEwEVARcBGQEbASMBJwErAS0BLwExATcBQgFEAUYBSAFRAVQBVgFYAVoBXgFgAWUBagFsAW4BcAFyAXQBeQF7AX0B+wH/AhgegB6CHoQe8yAUIBogHiAiICYgOiCsISL//wAAACAAIgAlADQANwA6AEEARgBKAE8AXwBhAGUAdAB2AHgAewCiAKUAqQCuALAAtwC6AL8AxwDSANgA4ADnAPEA+AD9AP8BCgEQARMBFQEXARkBGwEeAScBKwEtAS8BMQE2ATkBRAFGAUgBTAFUAVYBWAFaAV4BYAFiAWoBbAFuAXABcgF0AXYBewF9AfoB/gIYHoAegh6EHvIgEyAYIBwgIiAmIDkgrCEi////4//i/+H/3f/b/9n/2P/X/9X/1P/T/9L/0f/P/87/zf/M/6j/p/+k/6L/of+b/5kAAP9UAAAAAAAAAAAAAP9I/0kAAAAA/wz/I/8h/x//Hf8bAAD/Ev8P/w3/C/8JAAAAAP77/vn+9wAA/tL+0P7O/s3+yf7HAAD+v/69/rv+uf63/rcAAP6z/rEAAAAA/g/hq+Gp4acAAOBD4EDgP+A84DngJ9+230EAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB6AAAAhACMAJYAoACwAAAAAAC2AMYAAAAAAAAAAAAAAAAAwgAAAAAAAAAAAAAAwgDEAAAAAAAAANAAAAAAAAAAAAAAAAAAzgAAAAAAAAAAAAAAAADIAAAAAADKAMwAAAAAAAAAAADGAAAAAAAAAAAAAAAAAAAAAAAAAFUAGQAZABkAGQAZABkAIwAjACMAIwAjACMAKQApACkAKQAtADMAMwAzADMAMwAzADUANgA2ADYANgA6ADoAOgA6AD8AQABAAEAAQABAAEYAGQAzABkAMwAZADMAGwA1ABsANQAbADUAHAAeADgAHgA4AB4AOAAgADwAIQA9ACEAPQAhAD0AIQA9ACEAPQAjAEAAIwBAACMAQAAoAEMAKABDAC0ARgAtAC4AGQAzACMAQAAtAEYAAAEGAAABAAAAAAAAAAECAAAAAgAAAAAAAAAAAAAAAAAAAAEAAAMABAUABgcICQoLDA0ODxAAAAAAEQAAEgAAExQVFhcYABkaGxwAHR4AAB8gISIAIyQlJicoKSorLC0uLzAxADIAMzQ1ADY3ODk6Ozw9Pj9AQUIAAEMARABFRgBHSEkAABkZGwAAIykzMzMzMzM1NjY2Njo6Ojo/QEBAQEAAAAAAAFFKSwBeAABQTWMAAAAAIwAAAABMAAAAAAAATlMAAEBVAAAAAAAAT1RfABkZIwAAVldbXFhZAABGLQBiYGEAAABSWl0AGQAZAAAAAAAAIyMAIykpKToAAAAAAAAAAAAAsAAsS7AJUFixAQGOWbgB/4WwRB2xCQNfXi2wASwgIEVpRLABYC2wAiywASohLbADLCBGsAMlRlJYI1kgiiCKSWSKIEYgaGFksAQlRiBoYWRSWCNlilkvILAAU1hpILAAVFghsEBZG2kgsABUWCGwQGVZWTotsAQsIEawBCVGUlgjilkgRiBqYWSwBCVGIGphZFJYI4pZL/0tsAUsSyCwAyZQWFFYsIBEG7BARFkbISEgRbDAUFiwwEQbIVlZLbAGLCAgRWlEsAFgICBFfWkYRLABYC2wByywBiotsAgsSyCwAyZTWLBAG7AAWYqKILADJlNYIyGwgIqKG4ojWSCwAyZTWCMhsMCKihuKI1kgsAMmU1gjIbgBAIqKG4ojWSCwAyZTWCMhuAFAioobiiNZILADJlNYsAMlRbgBgFBYIyG4AYAjIRuwAyVFIyEjIVkbIVlELbAJLEtTWEVEGyEhWS0AAACwACsAsgECAisAtwF2YEs2KAAIK7cCrI1uTygACCsAsgMEByuwACBFfWkYRLAgiLgQAFRYsECIuCAAVVixAQGOWVlLsABSWLBAiLggAFRYsICIuEAAVVixAQGOWVlZAAAAFAAvACAAAAAM/1wAAAH+AAwCvAAMAAAAAAAwADAAMAAwAG4BFgHQAoACpALcAxQDbgOmA9YD+AQcBD4EigTEBQQFUAV+BbIF4AZIBpgHAAdgB6YH5ghOCJAI5gkWCW4JwAoMCoYK5gtgC5oL5AwwDJYM9A06DZINxA3mDhgOOg60Dx4Peg/aEDgQvBEMEUgRoBHwEhISmhLwE0ITshQkFIIUxhUYFXYV0hXwFkwWzBc+F7gYUBjOGRoZlhniGgAaXBqqGxgbOhtcG4wbvBvsHEQcnBz0HRodch2aHcYeVh7EIVIABQAA/zgB9AMgAAMABgAJAAwADwAPALMOAQIEK7MBAQUEKzAxESERIRsBIRMDERsBEQEhAwH0/gz6s/6al6zkrP6FAWazAyD8GAIwAYb+PgF4/RABeP6IAvD8xgGGAAAAAgBGAboBVwK+AA4AHQAdALAARViwAi8bsQIJPlmwAEVYsBEvG7ERCT5ZMDEBNjsBMhUUBg8BBiMiJjcnNjsBMhUUBg8BBiMiJjcBGAQYExADAjkGCwcJApYEGBMQAwI5BgsHCQICpBoRBQwHyRIIC9caEQUMB8kSCAsAAAIALf/8Ao4CwAA/AEMAlQCwAEVYsBQvG7EUCT5ZsABFWLAcLxuxHAk+WbAARViwEC8bsRAHPlmwAEVYsBgvG7EYBz5ZsABFWLAgLxuxIAc+WbAARViwNC8bsTQDPlmwAEVYsDwvG7E8Az5ZswgBAAQrsBgQsQkB9LAK0LAn0LAo0LAIELAp0LAAELAw0LAAELA40LAIELBA0LAoELBB0LBC0DAxNyMiJjU0NjsBNyMiJjU0NjsBNzYzMhYPATM3NjMyFg8BMzIWFRQGKwEHMzIWFRQGKwEHBiMiJj8BIwcGIyImNyU3IweqZQoODgptKW4KDg4KdhwDFg0LAhvPHAMWDQsCG2QKDg4KbCltCg4OCnUdAxYNCwIczx0DFg0LAgEjKc8puw0KCg7sDQoKDqUWEguepRYSC54NCgoO7A0KCg6pFhILoqkWEgvR7OwAAAUAN//4AwECxAAVACUAOwBRAGcAVQCwAEVYsAsvG7ELCT5ZsABFWLAbLxuxGwk+WbAARViwIy8bsSMDPlmwAEVYsCYvG7EmAz5ZszEBXQQrsDEQsADQsTwB9LALELFHAfSwJhCxUgH0MDETIi4CPQE0PgIzMh4CHQEUDgIDNDcBNjMyFhUUBwEGIyImBSIuAj0BND4CMzIeAh0BFA4CATI+Aj0BNC4CIyIOAh0BFB4CATI+Aj0BNC4CIyIOAh0BFB4C0CM4KBYWKTkjIjkoFhYpOWEEAecICwkNBP4ZCAsJDQHUIzgoFhYpOSMiOSgWFik5/kkWJRsPEB0lFRYlGw8QHSUBqxYlGw8QHSUVFiUbDxAdJQFeHTFAIwIjQTEeHTJAIgIjQTId/rMIBQKXCwwJCAX9aQsMEB0xQCMCI0ExHh0yQCICI0EyHQGRFSQxHAIdMiQVFSUxGwIeMiQU/poVJDEcAh0yJBUVJTEbAh4yJBQAAAMAMf/2Ao8CyAA3AEYAUwBwALAARViwGS8bsRkJPlmwAEVYsAAvG7EAAz5ZsABFWLAHLxuxBwM+WbIEBxkREjmyEBkHERI5siIZBxESObIjGQcREjmyMRkHERI5sjgZBxESObAZELE+AfSwBxCxRwH0skoHGRESObJLBxkREjkwMQUiJi8BDgEjIi4CPQE0NjcuAT0BND4CMzIeAh0BFAYHFz4BNz4BMzIWFRQHDgEHFx4BFRQGATY9ATQmIyIGHQEUHgITMjY3Jw4BHQEUHgICdQgLBWgydEcuTzkhX1YoJhouQSYiOysZW1G4FyoTAgoLCw4DFi8abQYGD/6dlz8wNkMIEx8DO2Qsz1RMGCw8CQcFbDo/HTNHKwJHZiAsSCwCIjorGBgpOB8CQlccvSFNLAQLDgsHBjBTI3AGCggLDwGiMGMCLz9BMAIRHiEn/nE7M9YdWzMCIDcpFwAAAAABAEYBugCjAr4ADgAQALAARViwAi8bsQIJPlkwMRM2OwEyFRQGDwEGIyImN2QEGBMQAwI5BgsHCQICpBoRBQwHyRIICwAAAAABAEf/dQFyAskAGQAdALAARViwCS8bsQkJPlmwAEVYsAwvG7EMCT5ZMDEFIiYnLgE1NDY3PgEzMhUUBw4BFRQWFxYVFAFfBAYCgIyMgAIGBBMLcnp6cguLAgFL1YeH1UsBAhMMBkjBfHzBSAYMEwAAAQA8/3UBZwLJABkAHQCwAEVYsA4vG7EOCT5ZsABFWLARLxuxEQk+WTAxFyI1NDc+ATU0JicmNTQzMhYXHgEVFAYHDgFPEwtyenpyCxMEBgKAjIyAAgaLEwwGSMF8fMFIBgwTAgFL1YeH1UsBAgAAAAEATAGSAWICwgA3ABAAsABFWLAYLxuxGAk+WTAxEwcGIyImNTQ2PwEnJjU0NjcyFh8BJyY2MzIWDwE3NjMyFhUUBg8BFx4BFRQGIyIvARcWBiMiJjfLWwkHCAwJBWdnDgwIBQYFWwgBDAkJDAEIWwkHCAwJBWdnBQkMCAcJWwgBDAkJDAECFT4GDQgHCgIxMQcMCAwBAwM+bQkNDQltPgYNCAgJAjExAgkICA0GPm0JDQ0JAAEAQABtAiwCUwAfABUAswgBAAQrsAgQsBDQsAAQsBfQMDEBIyImNTQ2OwE1NDYzMhYdATMyFhUUBisBFRQGIyImNQEdxQoODgrFDgsLDsUKDg4KxQ4LCw4BSA4KCg7CCw4OC8IOCgoOwgsODgsAAAABADb/lwCUAFkAGAAQALAARViwBS8bsQUDPlkwMRc0Nz4BJy4BPQE0NjMyFh0BFAYHDgEjIiY2CBsWAgsQEw4OEw0ODh8HBQpaCAUPJBoDEQ8VDhMTDhkqMA4OEgcAAAABAEIBDQFWAUUADgAPALMGAQAEK7AAELAN0DAxEyImNTQ2OwEyFhUUBisBXgsREQvcCxERC9wBDRELCxERCwsRAAAAAAEAUv/8AJQAWQAOABQAsABFWLAKLxuxCgM+WbEDAfQwMTc0NjMyFh0BFAYjIiY9AVITDg4TEw4OEzgOExMOGw4TEw4bAAAAAAH/+v98AesDIgAPAAgAsgUNAyswMQc0NwE2MzIWFRQHAQYjIiYGAwHEBw4JDAP+PAcOCQxvBwYDdg4MCQcG/IoODAAAAgAv//wCZQLFAB0AIAAvALAARViwCi8bsQoJPlmwAEVYsBovG7EaAz5Zsx4BAAQrsB4QsA7QsAAQsBXQMDElISImNTQ3AT4BMzIWFREzMhYVFAYrARUUBiMiJj0BEQEBvf6NDA8IAYIFCwkNEF8JDg4JXw4LCw7+sqsPDAoLAd0GBxAN/jAOCQkNlgsODgvDAZ7+YgAAAAABAED//AIYArwAFwAkALAARViwCi8bsQoJPlmwAEVYsBUvG7EVAz5ZsAoQsQMB9DAxNzQ3ASEiJjU0NjMhMhYVFAYHAQ4BIyImqQQBLf5/Cw4OCwGmCw4EAv7KAw0JCw8UBwgCZw4LCw4MCwUKBf19BwsNAAIAV//8AJkCAgANABsAKwCwAEVYsAMvG7EDBz5ZsABFWLAYLxuxGAM+WbADELEKAfSwGBCxEQH0MDETNDYzMhYdARQGIyImNRE0NjMyFh0BFAYjIiY1VxMODhMTDg4TEw4OExMODhMB4Q4TEw4bDhMTDv5yDhMTDhsOExMOAAAAAgA7/5cAmQICAA0AJgAkALAARViwAy8bsQMHPlmwAEVYsBMvG7ETAz5ZsAMQsQoB9DAxEzQ2MzIWHQEUBiMiJjUDNDc+AScuAT0BNDYzMhYdARQGBw4BIyImVxMODhMTDg4THAgbFgILEBMODhMNDg4fBwUKAeEOExMOGw4TEw794AgFDyQaAxEPFQ4TEw4ZKjAODhIHAAABADwAaAITAlgAGAAIALILAAMrMDElIiclJj0BNDclNjMyFhUUBgcNAR4BFRQGAf0HCP5gEhIBoAgHCgwJB/55AYcHCQxoBNgKEQIRCtgEDgoICwTIygQLCAoOAAIATwDWAh0B6gANABsADwCzFAEOBCuzBgEABCswMRMiJjU0NjMhMhYVFAYjBSImNTQ2MyEyFhUUBiNpCw8PCwGaCw8PC/5mCw8PCwGaCw8PCwG3DgsLDw8LCw7hDgsLDw8LCw4AAAAAAQBZAGgCMAJYABgACACyAAsDKzAxEzIXBRYdARQHBQYjIiY1NDY3LQEuATU0Nm8HCAGgEhL+YAgHCgwJBwGH/nkHCQwCWATYChECEQrYBA4KCAsEyMoECwgKDgACACX//AHiAsUAKwA5ACsAsABFWLAdLxuxHQk+WbAARViwNi8bsTYDPlmwHRCxEAH0sDYQsS8B9DAxNyImLwEmNjc+AT0BNC4CIyIGBwYjIiY1NDc+ATMyHgIdARQOAg8BBiMHNDYzMhYdARQGIyImNfQGCQELAQ0LVGkXKz4mOVklCAwKDQYoakwxUTgfIjlOKwgCDiITDg4TEw4OE7MJCYEKDgEFUUkCHzcpGDEqCgwKCQgwPB81RygCL0czHgVvEnsOExMOGw4TEw4AAAAAAgA4//wC3QLDABoAHQA3ALAARViwBi8bsQYJPlmwAEVYsBAvG7EQAz5ZsABFWLAYLxuxGAM+WbMbARQEK7IcBhgREjkwMTc0NwE+ATsBMhYXARYVFAYjIiYvASEHBiMiJiULATgEASsFEA4CDhAFASoEDgsJDQRS/mNSCBEKDgIKuLkSCAgCiAsODgv9eggICg4MCLS1Ew3qAZX+awAAAAMAaAAAApMCvAAeACoANAA4ALAARViwAy8bsQMJPlmwAEVYsBovG7EaAz5Zsx8BMgQrsg8fMhESObADELEoAfSwGhCxKwH0MDETNDYzITIWFxYdARQOAgceAx0BFA4CIyEiJjUBMj4CPQE0JisBERMyNj0BNCYrARFoDwsBBzxdHS0VIisVHzorGiRCXDn+6gsPARsnQjAbWlXs/lpqbWjtAqILDyEdLUECJDYoGwkIGyk3JAIsRzEbDwsBXxMkNiMCOkf+7f63TUICQUf+5wABAEn/9AK2AsgANAArALAARViwCy8bsQsJPlmwAEVYsAAvG7EAAz5ZsAsQsRsB9LAAELEmAfQwMQUiLgI9ATQ+AjMyHgIXHgEVFAYjIicuASMiDgIdARQeAjMyNjc2MzIWFRQHDgMBpUuAXTQ1XYBMK0k9NhoEBhALCwcsaUo/bE8tLk9sP0hqMggKCg8IGzhASgw4YYRLAkqEYzkOGiQWBAoHCw8HKDMwVXJCAkJzVTExMAgPCgoIGSgdDwAAAAACAGgAAALFArwAEwAhACgAsABFWLADLxuxAwk+WbAARViwDy8bsQ8DPlmxFAH0sAMQsR8B9DAxEzQ2OwEyHgIdARQOAisBIiY1NzI+Aj0BNC4CKwERaA8Lz1KJYzY2Y4lSzwsP6Ul2Ui0tUnZJtQKiCw81Xn9KAkqAXjYPCxYvUW0/Aj5uUjD9pAAAAAEAaP/8AlkCvAAbACoAsABFWLADLxuxAwk+WbAARViwGC8bsRgDPlmzDQETBCuwAxCxCgH0MDETNDYzITIWFRQGIyERITIWFRQGIyERFAYjIiY1aA8LAb8KDg4K/lsBeAoODgr+iA8LCw8CogsPDgoKDv7hDgoKDv7ZCw8PCwAAAQBJ//QCvALIADkAMQCwAEVYsAsvG7ELCT5ZsABFWLAALxuxAAM+WbMxASkEK7ALELEYAfSwABCxIwH0MDEFIi4CPQE0PgIzMhYXFhUUBiMiJy4BIyIOAh0BFB4CMzI+Ajc1IyImNTQ2OwEyFh0BFAcOAQGpU4NaMDFbgE5PbzEKDwsICClgSUBqTSopTm9GIUA5MhPaCg4OCvILDxIygQw5YoNKAkeDZDwpJQgNCw8HICcyVnI/AkR0VDANFh0QyQ4KCg4PC+UPDyY0AAAAAAEAKv/2AcgCwAAgACEAsABFWLAXLxuxFwk+WbAARViwAC8bsQADPlmxDgH0MDEXIiYnJjU0NjMyFhceATMyPgI1ETQ2MzIWFREUBgcOAflJYiAEDwsICwIfSzkgOCkXDwsLDyMdHEkKQDMGCAsPCAQwMBgvRi4BxgsPDwv+Pj1cHRwcAAEAaP/8ApQCwAAjADcAsABFWLADLxuxAwk+WbAARViwCi8bsQoJPlmwAEVYsBcvG7EXAz5ZsABFWLAgLxuxIAM+WTAxEzQ2MzIWFREBNjMyFhUUBwkBHgEVFAYjIiYnAQcVFAYjIiY1aA8LCw8BuggKChAI/vUBHQQEEAsHCgP+5a4PCwsPAqYLDw8L/koByAgQCgoI/vP+owUIBgsQBgQBXLCcCw8PCwAAAAABAGgAAAI7AsAAEgAhALAARViwAy8bsQMJPlmwAEVYsA4vG7EOAz5ZsQcB9DAxEzQ2MzIWFREhMhYVFAYjISImNWgPCwsPAYcKDg4K/l8LDwKmCw8PC/2KDgoKDg8LAAABAGj//AL8Ar8AIwA9ALAARViwAy8bsQMJPlmwAEVYsAovG7EKCT5ZsABFWLASLxuxEgM+WbAARViwIC8bsSADPlmzBwEXBCswMRM0NjsBMhcJATY7ATIWFREUBiMiJjURAQYjIicBERQGIyImNWgPCwUODAERAREKEAULDw8LCw/+/wkNDQn+/w4LCw4CpQsPD/5uAZIPDwv9cQsPDwsCSv6KDQ0Bdv21Cw4OCwAAAAIASf/0AwkCyAAVACsAKACwAEVYsAsvG7ELCT5ZsABFWLAALxuxAAM+WbEWAfSwCxCxIQH0MDEFIi4CPQE0PgIzMh4CHQEUDgInMj4CPQE0LgIjIg4CHQEUHgIBqFCBXDIzXIJQT4JcMjNcg01BbU8sLU9uQUFtTywtT24MO2OCSAJIg2Q7O2OCSAJIg2Q7LzFVckECQXNVMjFVckECQXNVMgAAAgBo//wCagK8ABcAJQAqALAARViwAy8bsQMJPlmwAEVYsBQvG7EUAz5ZsxgBDwQrsAMQsSMB9DAxEzQ2OwEyHgIdARQOAisBFRQGIyImNRMyPgI9ATQuAisBEWgPC+Q6X0UmLEtjN70PCwsP9DFQOSAfOE4vxgKiCw8dN08zAjdUOBzvCw8PCwEfGC1AJwIqPyoW/qkAAAACAEn/8gMJAsgAIQBCADgAsABFWLALLxuxCwk+WbAARViwAC8bsQADPlmwAEVYsBsvG7EbAz5ZsAsQsTQB9LAAELE/AfQwMQUiLgI9ATQ+AjMyHgIdARQGBxceARUUBiMiJi8BDgE3JjU0NjMyFh8BPgE9ATQuAiMiDgIdARQeAjMyNjcBqFCBXDIzXIJQT4JcMjAsUAYGEAsHCgVPLXEEDBALBwoFcyQoLU9uQUFtTywtT25BNl4mDDtjgkgCSINkOztjgkgCRn8yQwUKCAsQBQVIJirVCg0LEAUFaSpsPgJBc1UyMVVyQQJBc1UyIiAAAAAAAgBo//wCigK8ACEALQA3ALAARViwAy8bsQMJPlmwAEVYsBYvG7EWAz5ZsABFWLAeLxuxHgM+WbMiARkEK7ADELErAfQwMRM0NjMhMhYXHgEdARQOAgcTFhUUBiMiJwMjERQGIyImNQEyPgI9ATQmKwERaA8LAQxBZCAZHB83SyzHCBALDQrX5Q8LCw8BICxLNh9pYO8CogsPJSAZQyYCLEUyHwb+/goICxAOARj+9AsPDwsBOxYpOyYCR1L+xQAAAQBB//YCPQLGAEUANgCwAEVYsCQvG7EkCT5ZsABFWLAALxuxAAM+WbEOAfSwJBCxMgH0shkAMhESObI9JA4REjkwMQUiJicuATU0NjMyFx4BMzI+Aj0BNC4CJy4DPQE0PgIzMhYXHgEVFAYjIicuASMiDgIdARQeAhceAR0BFA4CAVVPfzwEBg8LCQg0cEgnQi4aES1MPD9aORoiPFIxR2gwBAcPCwoHLl02Jz8tGBEtUD56bCM9VQoxMQMKBwsPBi8sFSUzHgIcLCQdDA0jLz4oAidDMhwkJAMKCAsPBiMfFSQwGwIcLSUeDRlbTQIqRzIcAAEAMv/8AlYCvAAWACoAsABFWLAHLxuxBwk+WbAARViwEy8bsRMDPlmwBxCxAAH0sA7QsA/QMDEBIyImNTQ2MyEyFhUUBisBERQGIyImNQEq4AoODgoB9AoODgrgDwsLDwKMDgoKDg4KCg79igsPDwsAAAAAAQBd//UCmwLAACEALgCwAEVYsAkvG7EJCT5ZsABFWLAZLxuxGQk+WbAARViwAC8bsQADPlmxEAH0MDEFIi4CNRE0NjMyFhURFBYzMj4CNRE0NjMyFhURFA4CAXw/aU0qDwsLD31wNVY9IQ8LCw8qTGkLJ01wSgGDCw8PC/6CfYcgQGA/AYMLDw8L/oNLc04oAAAAAAEAOP/5ArcCwAAbADcAsABFWLAJLxuxCQk+WbAARViwES8bsREJPlmwAEVYsAAvG7EAAz5ZsABFWLAaLxuxGgM+WTAxBSImJwEmNTQ2MzIWFwkBPgEzMhYVFAcBDgErAQF2DA4F/uMCDwsKDQQBCwEMBA0JCw4C/uIFDgwCBwwLAowEBwkQDAn9jQJ0CAwPCQYE/XILDAAAAQA8//gEEwLAACoARACwAEVYsAUvG7EFCT5ZsABFWLANLxuxDQk+WbAARViwFS8bsRUJPlmwAEVYsB4vG7EeAz5ZsABFWLAnLxuxJwM+WTAxEyY1NDYzMhYXGwE+ATsBMhYXGwE2MzIWFRQHAw4BKwEiJicLAQ4BKwEiJz8DEAsLDgPVxwMLCwIKDAPH1ggRChAE6gQMCwILDQPGxgMNCwITCAKYBwYLEA8J/aUCXwgMDAj9oQJeFRAKBAr9dwoNDQoCTP20Cg0XAAAAAQBJ//wCiQLAACgANwCwAEVYsAovG7EKCT5ZsABFWLASLxuxEgk+WbAARViwHi8bsR4DPlmwAEVYsCYvG7EmAz5ZMDE3NDcTAy4BNTQ2MzIWFxsBPgEzMhYVFAcDExYVFAYjIiYnCwEOASMiJkkH+u4EBQ8KCAkF6OUFDAgKDQfv9wkPCggJBfLvBQwICg0UCAkBQAEvBQoFCQ8HBv7VASgHCQ4KCAn+z/7CCwkJDwcGATr+yQcJDgAAAAABADb//AKXAsAAGwAqALAARViwBi8bsQYJPlmwAEVYsA0vG7ENCT5ZsABFWLAYLxuxGAM+WTAxCQEmNTQ2MzIXEwE+ATMyFhUUBgcBERQGIyImNQFM/u8FEAsOCv4A/wUKCAoQBQP+8Q8LCw8BFQGBCAgLDw/+kwFtBgkPCgUKBf6D/wALDw8LAAAAAAEARwAAAnECvAAgAEwAsABFWLAPLxuxDwk+WbAARViwAC8bsQADPlmwAEVYsB8vG7EfAz5ZsAAQsRgB9LIHABgREjmwDxCxCAH0shcIDxESObAYELAZ0DAxMyImPQE0NjcBISImNTQ2MyEyFh0BFAYHASEyFhUUBiMhYAoPBAUB0/5GCg4OCgHoCg8EBf4tAcsKDg4K/gcOCAEHCQYCYA0KCg4OCAEHCQb9oA0KCg4AAQBi/34BdwK8ABcAHQCwAEVYsAMvG7EDCT5Zsw0CEwQrsAMQsQoC9DAxEzQ2OwEyFhUUBisBETMyFhUUBisBIiY1Yg8L6AgLCwjU1AgLCwjoCw8CogsPCwgIC/0OCwgICw8LAAEACf98AfoDIgAPAAgAsgsDAyswMQUUBiMiJwEmNTQ2MzIXARYB+gwJDgf+PAMMCQ4HAcQDbwkMDgN2BgcJDA78igYAAQA3/34BTAK8ABcAHQCwAEVYsBMvG7ETCT5ZswsCAwQrsBMQsQwC9DAxBRQGKwEiJjU0NjsBESMiJjU0NjsBMhYVAUwPC+gICwsI1NQICwsI6AsPaAsPCwgICwLyCwgICw8LAAH/6P9gAnD/jAAOAA8AswYBAAQrsAAQsA3QMDEHIiY1NDYzITIWFRQGIyECCQ0NCQJcCQ0NCf2koA0JCQ0NCQkNAAAAAgAz//QB6wIGADAAQgA+ALAARViwIC8bsSAHPlmwAEVYsCgvG7EoAz5ZsABFWLAALxuxAAM+WbMLAToEK7AgELESAfSwABCxMQH0MDEXIi4CPQE0PgIzMhYXNTQmIyIGBwYjIiY1NDY3PgEzMhcWFREUBiMiJj0BDgMnMj4CPQEuASMiBh0BFB4C+CRGOCMhOlIyNk4lWU8qRyAGBQkOCgQnUDFpODQNCwsNDSUwPSEnRjUfIFY3UVcYKTYMFCg8KAIoPioWDAoWTk4TDwMOCQkLAhEVODRc/tcLDg4LQBIjGxEuFyk6IzoID0E2AhwrHhAAAAIAXf/0AlgC3gAjADkANQCwAEVYsAwvG7EMBz5ZsABFWLAgLxuxIAM+WbAARViwFy8bsRcDPlmxJAH0sAwQsS8B9DAxEzQ2MzIWFRE+AzMyHgIdARQOAiMiLgInFRQGIyImNTcyPgI9ATQuAiMiDgIdARQeAl0NCwsOECozPyYuWUYrK0ZZLiZAMykQDQsLDv4qSTYfIDdJKChLOiMjOksCxQsODgv+xxkuIhUkRGM+Aj5jRSUUIiwYWQsODgsOHjhRMwIyUjkfIDpQMQIxUTkgAAAAAQA6//QCCQIKADEAKwCwAEVYsAsvG7ELBz5ZsABFWLAALxuxAAM+WbALELEaAfSwABCxJQH0MDEFIi4CPQE0PgIzMh4CFxYVFAYjIicuASMiDgIdARQeAjMyNjc2MzIWFRQHDgEBPjdfRigoRl83ITcvKBEHDgsLBh9LNCxLNyAhOUwsMk8fCAgJDwYmXQwrSGA2AjZgSisNFx0QBwsLDgYdKyI7UC4CLlE8IiofCA8JCQYnMQAAAAIAOv/0AhYCCgAKADAAMQCwAEVYsBkvG7EZBz5ZsABFWLAOLxuxDgM+WbMAASEEK7AZELEFAfSwDhCxJwH0MDEBLgMjIg4CBwUOASMiLgI9ATQ+AjMyHgIVFAYjIR4DMzI2NzYzMhYVFAHhAxktQiwmQjEgAwGNJlxFMltFKCVBWDQ2Vj0hDwn+cAMkNkUmN08fBwkKDgEXJ0c3IR41SSrQJi0mRmI8AjdhSCopSGA3CQ4wSjQbKB4HDQoJAAAAAAEALf/8AWMC3QArAEAAsABFWLAHLxuxBwc+WbAARViwHC8bsRwHPlmwAEVYsCgvG7EoAz5Zsw0BGQQrsBwQsQAB9LAB0LAj0LAk0DAxEyMiJjU0NjsBNTQ3NjMyFhceARUUBicuASMiHQEzMhYVFAYrAREUBiMiJjV7NwoNDgk3LShDEx0NCAsRCwwaDmefCg0OCZ8NCwsOAdENCgkNMlgtKAQDAg0ICwwCAgSBMQ0KCQ3+RAsODgsAAAAAAgA8/14CNwIKADQASgA+ALAARViwKy8bsSsHPlmwAEVYsCIvG7EiBz5ZsABFWLAALxuxAAU+WbM1ARcEK7AAELEMAfSwIhCxQAH0MDEFIicmNTQ2MzIWFxYzMj4CPQEOAyMiLgI9ATQ+AjMyHgIXNTQ2MzIWFREUBgcOAScyPgI9ATQuAiMiDgIdARQeAgE9e2QLDwoFBgNYbCxJNR4RKjRAJi5YRSoqRVguJkE0KhANCwsOIh8hX0AoTDskJDtMKChINh8gNkiiRggOCA8CAkEZMkoxShgqIRMiP1g3AjdaPyITHyoWUQsODgv+ZjhWHyEj9xwzRywCLEgzGxsyRy0CK0gzHQAAAQBd//wCEgLeACYAMQCwAEVYsAovG7EKBz5ZsABFWLATLxuxEwM+WbAARViwIy8bsSMDPlmwChCxGgH0MDETNDYzMhYVET4BMzIeAhURFAYjIiY1ETQmIyIOAhURFAYjIiY1XQ0LCw4aWEYwTDUbDQsLDlROJkAwGw0LCw4CxQsODgv+2i0+HzhNLv7dCw4OCwEaT18bMEMo/u4LDg4LAAIAXv/8AJsCywANABsAIwCwAEVYsBEvG7ERBz5ZsABFWLAYLxuxGAM+WbMDAQoEKzAxEzQ2MzIWHQEUBiMiJjUXNDYzMhYVERQGIyImNV4RDQ0SEg0NEQYNCwsODQsLDgKtDRERDRENERENswsODgv+LAsODgsAAAL/+/9dAJsCywANACcAOgCwAEVYsCEvG7EhBz5ZsABFWLAOLxuxDgU+WbAARViwES8bsREFPlmzAwEKBCuwERCxFwH0sBrQMDETNDYzMhYdARQGIyImNQMqAScuATU0NjMyFjMyNjURNDYzMhYVERQGXhENDRISDQ0RNgcMBQkMDQkGCwUbIg0LCw47Aq0NERENEQ0REQ38wQECCwkJDQEjJAIZCw4OC/3qPDoAAAAAAQBd//wB+wLeACEANwCwAEVYsAgvG7EIBz5ZsABFWLAKLxuxCgc+WbAARViwFi8bsRYDPlmwAEVYsB4vG7EeAz5ZMDETNDYzMhYVEQE2MzIWFRQPARcWFRQGIyIvAQcVFAYjIiY1XQ0LCw4BOQcKCg0Iu8gHDQsLCsR8DQsLDgLFCw4OC/3yAUQHDQoJCL73CAoLDAvyfWcLDg4LAAAAAAEAZP/8AJUC3gANABAAsABFWLAKLxuxCgM+WTAxEzQ2MzIWFREUBiMiJjVkDQsLDg0LCw4CxQsODgv9UAsODgsAAAAAAQBd//wDYAIKAEIAWwCwAEVYsAMvG7EDBz5ZsABFWLAMLxuxDAc+WbAARViwFi8bsRYHPlmwAEVYsB8vG7EfAz5ZsABFWLAvLxuxLwM+WbAARViwPy8bsT8DPlmwFhCxJgH0sDbQMDETNDYzMhYdAT4DMzIeAhc+AzMyHgIVERQGIyImNRE0JiMiDgIVERQGIyImNRE0JiMiDgIVERQGIyImNV0NCwsODB8oNSIhNyofCwwiLTkkLUkzGw0LCw5QRyA7LBoNCwsOUEUiPCwZDQsLDgHpCw4OC0YUJR0REh4oFhUoHxIfN08w/uALDg4LARpTWxguQyv+7AsODgsBHVBbHDJCJ/7vCw4OCwAAAAABAF3//AISAgoAJgA+ALAARViwAy8bsQMHPlmwAEVYsAovG7EKBz5ZsABFWLATLxuxEwM+WbAARViwIy8bsSMDPlmwChCxGgH0MDETNDYzMhYdAT4BMzIeAhURFAYjIiY1ETQmIyIOAhURFAYjIiY1XQ0LCw4aWEYwTDUbDQsLDlROJkAwGw0LCw4B6QsODgtKLT4fOE0u/t0LDg4LARpPXxswQyj+7gsODgsAAgA6//QCRgIKABUAKwAoALAARViwCy8bsQsHPlmwAEVYsAAvG7EAAz5ZsRYB9LALELEhAfQwMQUiLgI9ATQ+AjMyHgIdARQOAicyPgI9ATQuAiMiDgIdARQeAgE/OV9GJydHYDk5X0YnJ0dgNy1NNx8gOU0sLU03HyA5TQwrSGA2AjZgSisrSGA2AjZgSisuIztQLQIuUTwiIztQLQIuUTwiAAACAF3/XAJYAgoAIwA5AEIAsABFWLADLxuxAwc+WbAARViwDC8bsQwHPlmwAEVYsCAvG7EgBT5ZsABFWLAXLxuxFwM+WbEkAfSwDBCxLwH0MDETNDYzMhYdAT4DMzIeAh0BFA4CIyIuAicVFAYjIiY1NzI+Aj0BNC4CIyIOAh0BFB4CXQ0LCw4QKjM/Ji5ZRisrRlkuJkAzKRANCwsO/ipJNh8gN0koKEs6IyM6SwHpCw4OC10ZLiIVJERjPgI+Y0UlFCIsGPkLDg4Lrh44UTMCMlI5HyA6UDECMVE5IAAAAAIAPP9cAjcCCgAjADkARQCwAEVYsCAvG7EgBz5ZsABFWLAXLxuxFwc+WbAARViwAy8bsQMFPlmwAEVYsAwvG7EMAz5ZsBcQsSQB9LAMELEvAfQwMQUUBiMiJj0BDgMjIi4CPQE0PgIzMh4CFzU0NjMyFhUHIg4CHQEUHgIzMj4CPQE0LgICNw0LCw4RKTM/Ji5ZRisrRlkuJkAzKRANCwsO/ipJNh8gN0koKEs6IyM6S4sLDg4L/RkuIhUkRGM+Aj5jRSUUIiwYWQsODgsOHjhRMwIyUjkfIDpQMQIxUTkgAAAAAAEAKv/3AWACpQAsAEEAsABFWLANLxuxDQc+WbAARViwFi8bsRYHPlmwAEVYsAAvG7EAAz5ZsBYQsQYB9LAH0LAd0LAe0LAAELEiAfQwMQUiLgI1ESMiJjU0NjsBNTQ2MzIWHQEzMhYVFAYrAREUFjMyNjMyFhUUBw4BAQceNCcWNwkODgk3DQsLDqAJDg4JoDktGhsFCA4QDyMJECM1JAFODgkJDY4LDg4Ljg4JCQ3+tzcsCg0JDwYFCAAAAQA1//kCEQICABsAKgCwAEVYsA0vG7ENBz5ZsABFWLAVLxuxFQc+WbAARViwAy8bsQMDPlkwMSUOASsBIiYnAyY1NDYzMhYXGwE+ATMyFhUUBwMBQAUMCwILDAXNBA8LCwsEur0DCwoLDgPODgoLCwoBzAoFCw4MCP5JAbkICg4LBgf+MgAAAAEAQ//8AfcCAgAjADcAsABFWLAJLxuxCQc+WbAARViwDy8bsQ8HPlmwAEVYsBsvG7EbAz5ZsABFWLAhLxuxIQM+WTAxNzQ/AScmNTQ2MzIfATc2MzIWFRQPARcWFRQGIyIvAQcGIyImQwa1rAcOCgwIp6YKCwkNBq20Bw4KDAivrgoLCQ0TCAjh1gkICg0K0tAMDgkJB9bhCQgKDQrd2wwOAAAAAQA0/10CFwICACgAPACwAEVYsBgvG7EYBz5ZsABFWLAgLxuxIAc+WbAARViwAC8bsQAFPlmxDgH0shIAIBESObIcIAAREjkwMRciJicmNTQ2MzIWFx4BMzI2PwEDJjU0NjMyFhcbAT4BMzIWFRQHAw4BmxopFA4NCgQHBQweFyo4GQPkBA8LCwsEzLIDCwoLDgPPIlGjCAgFEAoNAgIFBTg5BwHXCgULDgwI/kgBuggKDgsGB/4SUEEAAAABADf/dQGrAskAOwAWALAARViwGi8bsRoJPlmzDwILBCswMQUuAz0BNC4CIyI1NDMyPgI9ATQ+Ajc2FhUUBgcOAx0BFA4CBx4DHQEUHgIXHgEVFAYBlj9PLA8KHDEnGBgnMRwKDyxPPwgNBwU2QCEKDxsmGBknGg4KIUA2BQcNiw0lMT8nTx0vIRITExIhLx1PJz8xJQ0CCQkGCAIOHyg1JUshMCIWBwgWITAhSyU1KB8OAggGCQkAAQB5/3wApQMiAA0ACACyAwoDKzAxEzQ2MzIWFREUBiMiJjV5DQkJDQ0JCQ0DDAkNDQn8hgkNDQkAAAAAAQA1/3UBqQLJADsAFgCwAEVYsAAvG7EACT5ZswsCDwQrMDETHgMdARQeAjMyFRQjIg4CHQEUDgIHBiY1NDY3PgM9ATQ+AjcuAz0BNC4CJy4BNTQ2Sj9PLA8KHDEnGBgnMRwKDyxPPwgNBwU2QCEKDxsmGBknGg4KIUA2BQcNAskNJTE/J08dLyESExMSIS8dTyc/MSUNAgkJBggCDh8oNSVLITAiFgcIFiEwIUslNSgfDgIIBgkJAAIAPv/2Ag4CxgA7AEYANQCwAEVYsBAvG7EQCT5ZsABFWLA4LxuxOAM+WbMkATEEK7MMAUAEK7M/AQAEK7MhARQEKzAxNy4DPQE0PgI7ATc+ATMyFg8BHgEXFhUUBiMiJy4BJwMWMzI2NzYzMhYVFAcOASMqAScHDgEjIiY3AxQWFxMjIg4CFewnQC4ZKEZfNw8NAgwKDA8DDSo9GgkNCwsIFzQgVBISME8hCQoJDQclXkIKEwoQAgwKDA8DaEo7UgksSzcgZw0yQk4rAjZgSitECAwRDkAKKRgJCwsOCBYkCP5QAyghCQ4JCQcnMgJQCAwRDgFOR28YAasiO1AuAAABAEIAAAJJAsYAOQBGALAARViwEy8bsRMJPlmwAEVYsDcvG7E3Az5ZswwBBAQrsDcQsQMB9LATELEiAfSwDBCwJ9CwBBCwLtCwAxCwMNCwMdAwMTc0PwERIyImNTQ2OwE1NDY3PgEzMhYXFhUUBiMiJy4DIyIHBh0BITIWFRQGIyERITIWFRQGIyEiQgxOQgoODgpCISAcTC5JXiEHDgsLCQ8gJy8eRisyARYKDg4K/uoBYgoODgr+Hg0NCwMSAQQOCgoOdjlcIBweNicJCgsNCREeFQwrMmJ3DgoKDv7+DgoKDQABADX//AJ6AsAAPABOALAARViwJy8bsScJPlmwAEVYsC4vG7EuCT5ZsABFWLAMLxuxDAM+WbMBAQcEK7MhARkEK7AHELAQ0LABELAX0LAhELA00LAZELA70DAxJTMyFhUUBisBFRQGIyImPQEjIiY1NDY7ATUjIiY1NDY7AQMmNTQ2MzIWFxsBNjMyFhUUBwMzMhYVFAYrAQFwwgkODgnCDgsLDsIJDg4JwsIJDg4JsPEGDwsICwXx8wkPCg0H8rEJDg4JwqoNCgkNaAsODgtoDQkKDWINCQkOAVwJCQsOCAj+lwFrDg4KCQr+pA4JCQ0AAAAAAwA1//QDCQLIABUAKwBcADcAsABFWLALLxuxCwk+WbAARViwAC8bsQADPlmzTwEsBCuzNwFEBCuwABCxFgL0sAsQsSEC9DAxBSIuAj0BND4CMzIeAh0BFA4CJzI+Aj0BNC4CIyIOAh0BFB4CNyIuAj0BND4CMzIWFxYVFAYjIicuASMiDgIdARQeAjMyNjc+ATMyFhUUBw4BAZ5MhGE4OGKFTEyEYTg4YoVMR3pZMzJZeUdHelkzMll5TCdCMRwcMkInLTwYCQ0JBwkUMSAeMiUVFiUzHSIxFwIHBQgMBxw9DDlig0oCSoNjOjlig0oCSoNjOhw1W3lFAkV5WjQ1W3lFAkV5WjSWHjNEJwImRTQeHRUHCwkMBxEZFyk2HgIeNygYFxUCAwwICgUYHgAAAAMAOgElAT4CvwArADsASQAyALAARViwHS8bsR0JPlmzQgE8BCuzLAIABCuzCQI1BCuwHRCxEAL0sAAQsCXQsCUvMDETIi4CPQE0NjMyFhc1NCYjIgYHBiMiJjU0Nz4BMzIXFh0BFAYjIiY9AQ4BJzI+Aj0BLgEjIgYdARQWByImNTQ2OwEyFhUUBiOuFCcfE0U3GycRLSYVJw8GBQgKDBcsGzogHAsICAoRMR4TIxoQESgcJiwqRQgMDAjcCAwMCAGbCxchFwItMAYFBSYnCwcDCggMBQsLIBw0oAgKCggbFhkkCxQdERsFBiAZAhsdmgwICAwMCAgMAAAAAAIANwArAb8B0wAVACsAFACyCgADK7AAELAW0LAKELAg0DAxJSIvASY1ND8BNjMyFhUUDwEXFhUOASMiLwEmNTQ/ATYzMhYVFA8BFxYVFAYBqQsIiQoKiQgLCQ0Gfn4GAQzVCwiJCgqJCAsJDQZ+fgYNKwuzDQkJDbMLDAkKB62vCQgJDAuzDQkJDbMLDAkKB62vCAkJDAAABAAiAWgBfgLGABUAKwBDAEwAKQCwAEVYsAsvG7ELCT5ZsxYCAAQrsy8CSgQrs0QCPQQrsAsQsSEC9DAxEyIuAj0BND4CMzIeAh0BFA4CJzI+Aj0BNC4CIyIOAh0BFB4CJzQ7ATIWFRQGBxcWFRQjIi8BIxUUIyI1NzI2NTQmKwEV0CU/LxsbL0AkJT8vGxsvQCQhOCkYFyo4ISE4KRgXKjggDkAbJhcTJgUNCAYxKA4OSxMUFRIvAWgcLz8kASQ/MBwcLz8kASQ/MBwTGSo5IAEgOCoZGSo5IAEgOCoZ6Q4cGhQcBi0GBg0IOzUODkwSDhAPPwAAAAACAEoBnAF4AsIAFQArAB0AsABFWLALLxuxCwk+WbMWAQAEK7ALELEhAfQwMRMiLgI9ATQ+AjMyHgIdARQOAicyPgI9ATQuAiMiDgIdARQeAuEeNioZGSo2Hh42KhkZKjYeFiUbDw8bJRYWJRsPDxslAZwYKDUdAh01KBgYKDUdAh01KBgsERwlFAIUJRwRERwlFAIUJRwRAAEAUgD7AJQBWAAOAAkAswMBCgQrMDETNDYzMhYdARQGIyImPQFSEw4OExMODhMBNw4TEw4bDhMTDhsAAAMALwElAVcCwQAVACMANQAjALAARViwCy8bsQsJPlmzHAEWBCuzJAIABCuwCxCxLQL0MDETIi4CPQE0PgIzMh4CHQEUDgIHIiY1NDYzITIWFRQGIycyNj0BNC4CIyIGHQEUHgLCHzUmFRYmNSAfNSYVFiY2nggMDAgBAAgMDAh/LTcQGyUWLTcQGyUBmxcoNR0CHjUoGBcoNR0CHjUoGHYMCAgMDAgIDJ0+LAIWKB0RPiwCFycdEQACAEQAKwHMAdMAFQAsABQAsgAKAyuwABCwFtCwChCwINAwMQEyHwEWFRQPAQYjIiY1ND8BJyY1NDYjMh8BFhUUDwEGIyImNTQ/AScuATc+AQEmCwiJCgqJCAsJDQZ+fgYNwwsIiQoKiQgLCQ0Gfn4DBAEBDAHTC7MNCQkNswsMCQkIra8HCgkMC7MNCQkNswsMCQkIra8FBwUJDAACADT/9wHxAsAAKwA5ADUAsABFWLA2LxuxNgk+WbAARViwAC8bsQAHPlmwAEVYsBwvG7EcAz5ZsQ8B9LA2ELEvAfQwMQEyHwEWBgcOAR0BFB4CMzI2NzYzMhYVFAcOASMiLgI9ATQ+Aj8BPgEzNxQGIyImPQE0NjMyFhUBIg4CCwENC1RpFys+JjlZJQgMCg0GKGpMMlA4HyI5TSwIAQkGIhMODhMTDg4TAgkSgQoOAQVRSQIfNykYMSoKDAoKBzA8HzVHKAIuSDMeBW8JCXsOExMOGw4TEw4AAAAAAQBCAQ8BzgFDAA4ADwCzBgEABCuwABCwDdAwMRMiJjU0NjMhMhYVFAYjIVwLDw8LAVgLDw8L/qgBDw8LCw8PCwsPAAABAEIBDwNAAUMADgAPALMGAQAEK7AAELAN0DAxEyImNTQ2MyEyFhUUBiMhXAsPDwsCygsPDwv9NgEPDwsLDw8LCw8AAAEATQH9AKsCvwAYABAAsABFWLAWLxuxFgk+WTAxExQHDgEXHgEdARQGIyImPQE0Njc+ATMyFqsIGxYCCxATDg4TDQ4OHwcFCgKwCAUPJBoDEQ8VDhMTDhkqMA4OEgcAAAEAOwH+AJkCwAAYABAAsABFWLAMLxuxDAk+WTAxEzQ3PgEnLgE9ATQ2MzIWHQEUBgcOASMiJjsIGxYCCxATDg4TDQ4OHwcFCgINCAUPJBoDEQ8VDhMTDhkqMA4OEgcAAAEANv+XAJQAWQAYABAAsABFWLAFLxuxBQM+WTAxFzQ3PgEnLgE9ATQ2MzIWHQEUBgcOASMiJjYIGxYCCxATDg4TDQ4OHwcFCloIBQ8kGgMRDxUOExMOGSowDg4SBwAAAAIATQH9AV8CvwAYADEAHQCwAEVYsBYvG7EWCT5ZsABFWLAvLxuxLwk+WTAxARQHDgEXHgEdARQGIyImPQE0Njc+ATMyFgcUBw4BFx4BHQEUBiMiJj0BNDY3PgEzMhYBXwgbFgILEBMODhMNDg4fBwUKtAgbFgILEBMODhMNDg4fBwUKArAIBQ8kGgMRDxUOExMOGSowDg4SBwgIBQ8kGgMRDxUOExMOGSowDg4SBwAAAgA7Af4BTQLAABgAMQAdALAARViwDC8bsQwJPlmwAEVYsCUvG7ElCT5ZMDETNDc+AScuAT0BNDYzMhYdARQGBw4BIyImNzQ3PgEnLgE9ATQ2MzIWHQEUBgcOASMiJjsIGxYCCxATDg4TDQ4OHwcFCrQIGxYCCxATDg4TDQ4OHwcFCgINCAUPJBoDEQ8VDhMTDhkqMA4OEgcICAUPJBoDEQ8VDhMTDhkqMA4OEgcAAAACADb/lwFIAFkAGAAxAB0AsABFWLAFLxuxBQM+WbAARViwHi8bsR4DPlkwMRc0Nz4BJy4BPQE0NjMyFh0BFAYHDgEjIiY3NDc+AScuAT0BNDYzMhYdARQGBw4BIyImNggbFgILEBMODhMNDg4fBwUKtAgbFgILEBMODhMNDg4fBwUKWggFDyQaAxEPFQ4TEw4ZKjAODhIHCAgFDyQaAxEPFQ4TEw4ZKjAODhIHAAAAAAEAbwDkAWcB3AAVAAgAsgsAAyswMTciLgI9ATQ+AjMyHgIdARQOAusaLSEUFCMtGBgtIhUUIS7kEyIsGgIZLSITEyItGQIaLCITAAADAFL//AJWAFkADQAbACkANwCwAEVYsAovG7EKAz5ZsABFWLAYLxuxGAM+WbAARViwJi8bsSYDPlmwChCxAwH0sBHQsB/QMDElNDYzMhYdARQGIyImNSc0NjMyFh0BFAYjIiY1JzQ2MzIWHQEUBiMiJjUCFhIODhISDg4S4hIODhISDg4S4hIODhISDg4SOA4TEw4bDhMTDhsOExMOGw4TEw4bDhMTDhsOExMOAAAAAAEANwArAPMB0wAVAAgAsgoAAyswMTciLwEmNTQ/ATYzMhYVFA8BFxYVFAbdCwiJCgqJCAsJDQZ+fgYNKwuzDQkJDbMLDAkKB62vCAkJDAAAAQBEACsBAAHTABYACACyAAoDKzAxEzIfARYVFA8BBiMiJjU0PwEnLgE3PgFaCwiJCgqJCAsJDQZ+fgMEAQEMAdMLsw0JCQ2zCwwJCQitrwUHBQkMAAAAAAEAN//0ApICyABbACoAsk5UAyuyNTsDK7IaEwMrsE4QsAzQsDsQsCDQsBoQsEHQsBMQsEfQMDElFAcOAyMiLgInIyImNTQ2OwEmNTQ2NyMiJjU0NjsBPgMzMh4CFxYVFAYjIicuASMiDgIHITIWFRQGIyEOARUUFyEyFhUUBiMhHgMzMjY3NjMyFgKSBRQtN0InNFpINAxHCg4OCj8DAgJACg4OCkoNM0VWMSlEOC0UBg4KDgcnV0MmRDcqDAEICg4OCv7vAgMDARMKDg4K/vYMKjtKKj5YIggMCg2IBwccMSQVJURfOQ4KCg4bHREhEQ4KCg42W0IlEyEuGwgICg4LNDgeNkosDgoKDhAgER8bDgoKDi9OOB4/MgsMAAAAAAIAFgGEAoYCvAAVADcARACwAEVYsAcvG7EHCT5ZsABFWLAYLxuxGAk+WbAARViwHy8bsR8JPlmwAEVYsBwvG7EcBz5ZsAcQsQAC9LAO0LAP0DAxEyMiJjU0NjsBMhYVFAYrAREUBiMiNRM0OwEyHwE3NjsBMhYVERQGIyI9AQcGIyIvARUUBiMiJjV/WAcKCgfTBwoKB1gKCBHOEQUKBnd3BgoEBwoKCBFpBwkKB2kKCAcKApoKBwcKCgcHCv77CAkRARYRCbW1CQoH/uoICRHinQoKneIICQkIAAAfADL/nAKEArwADgATABsAIwAvADcAQwBdAGkAbQCDAIsApAC6AMoA5wDzARcBIQE1AWsBhQGrAbQBwAHIAdAB3wHkAgACCAAAJTYjIgYVFjMyNyMGIyI1NzIVIzQnIjU0MzIVFBciNTQzMhUUBzI2NTQmIyIGFRQWJSI1NDMyFRQHMjY1NCYjIgYVFBYlMzUjNTMyFzM1IwYrATUzMhYXMzUjFTMVIxcyNjU0JiMiBhUUFgUhESEDMjcjBiMiNTQzMhczNSMHJiMiBhUUJyI1NDMyFRQHMzUjNTMVIxUzNSM1ByYjIgYdASMVMxUjFzM1IzU2MxUUMzI1NCMiBzUjFTMVIyczNxYzMjY1NCMiBzUjFTMXIhUUMzI/ATM1IxUzByczNSMVMxYXHgEXBiM2JgM0NjMyFhUUBgcuARMzNx4BMzI1NC4CNTQzMhczNSMHJiMiBhUUHgIVFCMiJyMnIiY1NDceARcGBxUjFTMVFDMyNycGIyI9ATM1IzU3HgEzMjY1NCYjIgcuAQc2NTQuAiMiDgIVFBYXBhUUHgIzMjceATMyNjcnDgEjIiYnPgEHMzUjNTQzMh0BIxUzNSM1NCMiBzUjFTMVIxcVMwYHLgEnNjU0JiMiBhUUFwYVFDMyNxYzMjcnBiMiJz4BNzM1ByI1NDceARcGJzQ2MzIXBhUUMxUjNzQzMhUUByYDNjcWBgcuARM2IyIGFRQzMjcjBiMiNTcyFSM0BzM1IzUzFSMVMzUjNTM1IxUzFSM1MzUjFTMVIyUiFRQzMjU0ARECFQkLARQPAwcCBwoHBw40CAgIBwgICAgJDAwJCQwMAVkICAgICQwMCQkMDP5kHgoEBQEHBwEFBAwFBAIIMwcHRgkMDAkJDAwByv2uAlKSFgIIAgwQDgoFCAgBBwkLEGEICAdnFwUOBRcGCgQFCAsHBwZcGggEAwYHCAgEEgYGEAYEBQkJBw8KAxIGMAcLDAYNBREFCAkGGQUCBAMFAgIGAgKeDwwNEAoIERU3BwECBgUOCAkHBQUFBwYCAwgHBwcJCAUGBgcpFx0QDicVDwoHBwwLAwUBBAQNDY4HFg4VHR0VIxkCGxQJDBgkFxkoHQ8PEFIRHicXPykZJRcgLgIHCBMQDxwTCxjGFgQHBgQWBgwJBREGBuMGAgQDBQQLBwcICQYNEgkGBQcKAwUBAwMDAwQCBSMKBAQGBASLAwMCAQEGDoMFBgUGcR4MEQQOChMqAhUIDBUOBAcBCAoHBw7YHQgWCB0ICB0IFggdCAgBxAcHBxIWCwoUDgcMEQwMKxAPDxBKEA8PEAUMCQkLCwkKCwUQDw8QBQwJCQsLCQoLSwcQCBcIEgUIFAcpCAwJCQsLCQoLrQMg/UMXEBYWEBYGBxAOHFENDQ0NUAcZGQcHNAICCQoBBxkHBxAJAQYHCAsKBxlCCAgOBxQJGwcyBwkQHwcHFBQHBwUIBgoECAIIAWENEBURDRgNERn+rwQCAw0GBQICAwQHDQUFBwUGBQMCAwQJgx8XGBANKxoMYQkHFA0NAgcFFAcLtgsOHxcXHSYUEgEPEw0bFQ0OGB8QFh4RHD8UIhkOLRoTMiwCDRATFg8U4QcPCgcSBwcTDgsKBxkwBwUEAwYEBQcFBwgGBgYECw4GBgwBBQUDBgUHGwoFBAQHBQMkBwUBAgIFBQQFBgYDBgEvFA4RJhkLF/7IFgwJFA4HDBEMDCMHEhIHBykHBxAQBwcpBgcHBwcAAAAAACQBtgABAAAAAAAAAEAAAAABAAAAAAABACMAQAABAAAAAAACAAcAYwABAAAAAAADACEAagABAAAAAAAEACMAQAABAAAAAAAFAA0AiwABAAAAAAAGAAQAmAABAAAAAAAHAFkAnAABAAAAAAAIAA0A9QABAAAAAAAJAA0A9QABAAAAAAAKAhEBAgABAAAAAAALABIDEwABAAAAAAAMABIDEwABAAAAAAANAhEBAgABAAAAAAAOACoDJQABAAAAAAAQACMAQAABAAAAAAARACMAQAABAAAAAAASACMAQAADAAEECQAAAIADTwADAAEECQABAEYDzwADAAEECQACAA4EFQADAAEECQADAEIEIwADAAEECQAEAEYDzwADAAEECQAFABoEZQADAAEECQAGAAgEfwADAAEECQAHALIEhwADAAEECQAIABoFOQADAAEECQAJABoFOQADAAEECQAKBCIFUwADAAEECQALACQJdQADAAEECQAMACQJdQADAAEECQANBCIFUwADAAEECQAOAFQJmQADAAEECQAQAEYDzwADAAEECQARAEYDzwADAAEECQASAEYDz0NvcHlyaWdodCAoQykgMjAwNiwgMjAwNyBIb2VmbGVyICYgQ28uIGh0dHA6Ly93d3cudHlwb2dyYXBoeS5jb21Db3B5cmlnaHQgKEMpIEgmQ28gfCB0eXBvZ3JhcGh5LmNvbVJlZ3VsYXIxNzEyNDctODg0NzQtMjAxNTA2MjMtMjQyMy0xNDAyMTlWZXJzaW9uIDEuMzAxRm9udEdvdGhhbSBpcyBhIHRyYWRlbWFyayBvZiBIb2VmbGVyICYgQ28uLCB3aGljaCBtYXkgYmUgcmVnaXN0ZXJlZCBpbiBjZXJ0YWluIGp1cmlzZGljdGlvbnMuSG9lZmxlciAmIENvLlRoaXMgc29mdHdhcmUgaXMgdGhlIHByb3BlcnR5IG9mIEhvZWZsZXIgJiBDby4gWW91IG1heSBub3QgY29weSwgbW9kaWZ5LCBkaXN0cmlidXRlLCBvciBkb3dubG9hZCB0aGlzIHNvZnR3YXJlLCBvciBpbnN0YWxsIGl0IHVwb24gYW55IGNvbXB1dGVyLCBvciBob3N0IGl0IGZyb20gYW55IGxvY2F0aW9uLiBZb3VyIHJpZ2h0IHRvIHVzZSB0aGlzIHNvZnR3YXJlIGlzIHN1YmplY3QgdG8gdGhlIFRlcm1zIG9mIFNlcnZpY2UgYWdyZWVtZW50IHRoYXQgZXhpc3RzIGJldHdlZW4geW91IGFuZCBIb2VmbGVyICYgQ28uIElmIG5vIHN1Y2ggYWdyZWVtZW50IGV4aXN0cywgeW91IG1heSBub3QgdXNlIHRoaXMgc29mdHdhcmUgZm9yIGFueSBwdXJwb3NlLiBGb3IgbW9yZSBpbmZvcm1hdGlvbiwgcGxlYXNlIHZpc2l0IGh0dHA6Ly93d3cudHlwb2dyYXBoeS5jb20vd2ViZm9udC1zb2Z0d2FyZSwgb3IgY29udGFjdCBIb2VmbGVyICYgQ28uIGF0IHd3dy50eXBvZ3JhcGh5LmNvbSAxNzEyNDctODg0NzQtMjAxNTA2MjMtMjQyMy0xNDAyMTl3d3cudHlwb2dyYXBoeS5jb21odHRwOi8vd3d3LnR5cG9ncmFwaHkuY29tL3dlYmZvbnQtc29mdHdhcmUAQwBvAHAAeQByAGkAZwBoAHQAIAAoAEMAKQAgADIAMAAwADYALAAgADIAMAAwADcAIABIAG8AZQBmAGwAZQByACAAJgAgAEMAbwAuACAAaAB0AHQAcAA6AC8ALwB3AHcAdwAuAHQAeQBwAG8AZwByAGEAcABoAHkALgBjAG8AbQBDAG8AcAB5AHIAaQBnAGgAdAAgACgAQwApACAASAAmAEMAbwAgAHwAIAB0AHkAcABvAGcAcgBhAHAAaAB5AC4AYwBvAG0AUgBlAGcAdQBsAGEAcgAxADcAMQAyADQANwAtADgAOAA0ADcANAAtADIAMAAxADUAMAA2ADIAMwAtADIANAAyADMALQAxADQAMAAyADEAOQBWAGUAcgBzAGkAbwBuACAAMQAuADMAMAAxAEYAbwBuAHQARwBvAHQAaABhAG0AIABpAHMAIABhACAAdAByAGEAZABlAG0AYQByAGsAIABvAGYAIABIAG8AZQBmAGwAZQByACAAJgAgAEMAbwAuACwAIAB3AGgAaQBjAGgAIABtAGEAeQAgAGIAZQAgAHIAZQBnAGkAcwB0AGUAcgBlAGQAIABpAG4AIABjAGUAcgB0AGEAaQBuACAAagB1AHIAaQBzAGQAaQBjAHQAaQBvAG4AcwAuAEgAbwBlAGYAbABlAHIAIAAmACAAQwBvAC4AVABoAGkAcwAgAHMAbwBmAHQAdwBhAHIAZQAgAGkAcwAgAHQAaABlACAAcAByAG8AcABlAHIAdAB5ACAAbwBmACAASABvAGUAZgBsAGUAcgAgACYAIABDAG8ALgAgAFkAbwB1ACAAbQBhAHkAIABuAG8AdAAgAGMAbwBwAHkALAAgAG0AbwBkAGkAZgB5ACwAIABkAGkAcwB0AHIAaQBiAHUAdABlACwAIABvAHIAIABkAG8AdwBuAGwAbwBhAGQAIAB0AGgAaQBzACAAcwBvAGYAdAB3AGEAcgBlACwAIABvAHIAIABpAG4AcwB0AGEAbABsACAAaQB0ACAAdQBwAG8AbgAgAGEAbgB5ACAAYwBvAG0AcAB1AHQAZQByACwAIABvAHIAIABoAG8AcwB0ACAAaQB0ACAAZgByAG8AbQAgAGEAbgB5ACAAbABvAGMAYQB0AGkAbwBuAC4AIABZAG8AdQByACAAcgBpAGcAaAB0ACAAdABvACAAdQBzAGUAIAB0AGgAaQBzACAAcwBvAGYAdAB3AGEAcgBlACAAaQBzACAAcwB1AGIAagBlAGMAdAAgAHQAbwAgAHQAaABlACAAVABlAHIAbQBzACAAbwBmACAAUwBlAHIAdgBpAGMAZQAgAGEAZwByAGUAZQBtAGUAbgB0ACAAdABoAGEAdAAgAGUAeABpAHMAdABzACAAYgBlAHQAdwBlAGUAbgAgAHkAbwB1ACAAYQBuAGQAIABIAG8AZQBmAGwAZQByACAAJgAgAEMAbwAuACAASQBmACAAbgBvACAAcwB1AGMAaAAgAGEAZwByAGUAZQBtAGUAbgB0ACAAZQB4AGkAcwB0AHMALAAgAHkAbwB1ACAAbQBhAHkAIABuAG8AdAAgAHUAcwBlACAAdABoAGkAcwAgAHMAbwBmAHQAdwBhAHIAZQAgAGYAbwByACAAYQBuAHkAIABwAHUAcgBwAG8AcwBlAC4AIABGAG8AcgAgAG0AbwByAGUAIABpAG4AZgBvAHIAbQBhAHQAaQBvAG4ALAAgAHAAbABlAGEAcwBlACAAdgBpAHMAaQB0ACAAaAB0AHQAcAA6AC8ALwB3AHcAdwAuAHQAeQBwAG8AZwByAGEAcABoAHkALgBjAG8A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AAAAAAAAAAAAAAAAAAD/9v/nAAAAAAAAAAAAAAAA//EAAP+c//b/nAAAAAD/9gAA//EAAAAAAAAAAAAAAAAAAAAAABQAAP/2AAAAAAAAAAAAAAAA//YAAP/x//EAAAAAAAAAAAAAAAD/7AAA/+z/8f/2/+IAAAAKAAAAAAAA//EAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//YAAAAAAAAAAAAAAAAAAAAAAAAAAP/7AAAAAP/7AAAAAAAA/+cAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/xAAD/8QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/zgAA//b/9v/x/+L/4gAA/9gAAP/2//YAAAAAAAAAAAAA/+IAAAAA/+cAAP/O/+z/5//sAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/nAAD/7P/E/84AAP/OAAAAAAAAAAD/2AAAAAD/nP/s/43/nAAA/34AAAAA//b/sAAA/4gAAAAA//YAAAAA//sAAP/Y/+z/+wAAAAAAAAAAAAAAAAAA/8QAAP/Y/9j/pgAAAAAAAP/sAAAAAP/E/84AAP/EAAAAAAAA/9gAAP/i//v/yQAA/9j/3f/O/8T/2AAAAAAAAAAA/9j/7P/sAAAAAP/YAAD/2AAAAAAAAAAAAAAAAAAAAAAAAP/i/+wAAAAAAAAAAAAAAAD/2AAAAAAAAAAAAAD/+wAAAAAAAAAA/7oAAAAAAAAAAAAAAAD/+wAA//b/8f/2AAAAAAAAAAAAAAAA//sAAP+cAAD/nAAAAA8AAAAKAAAAAAAAAAAAAAAAAAAAAAAAABQAAAAAAAAAAAAPAAAABQAAAAoAAAAKAAAAAAAAAAAAAAAAAAD/yQAAAAD/3QAA/78AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/7AAD/9gAA/+z/8QAA/+cAAAAAAAAAAAAAAAAAAAAA//YAAAAA//sAAAAAAAr/+wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKAAAAAAAAAAAAAAAAAAAAAAAA//EAAAAA//b/8QAA/+L/5//n/+L/9gAAAAAAAAAA/+wAAAAAAAAAAAAAAAAAAAAA//sAAAAAAAAAAAAAAAAAAAAA//YAAAAAAAAAAAAAAAAAAP/7AAAAAP/x//b/8f/x//sAAAAA/6b/yf+S//EAAAAAAAAAAAAAAAD/7P95/7oAAP/sAAAAAAAA/3n/zv+c/4P/nP+m/87/g/+m/7r/2P/Y/5wAAAAAAAAAAAAAAAAAAP+NAAD/pv/OAAD/nP+c/5z/nP+c/5IAAAAA/+cAAP/sAAAAAAAAAAAAAP/2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/xAAD/8QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/8QAAAAAAAAAAAAD/+wAAAAAAAAAA/5z/2AAA/+cAAAAAAAD/9gAA/+z/9v+6AAAAAP/2AAAAAAAA/7r/7P+I/7//iP/Y/+f/v//E/9j/7AAA/9gAAAAAAAAAAAAAAAAAAP/EAAAAAP/sAAD/2AAA/90AAP/Y/8kAAAAA/6b/3f+X/+wAAAAA//b/9v/x/+z/9v+6/9MAAP/2AAAAAAAA/7//8f+c/8T/nP/d/+L/xP/O/93/8f/x/90AAAAAAAAAAAAAAAAAAP/EAAD/nP/nAAD/3f/d/93/2P/d/8kAAAAAAAD/zgAA/+IAAP/2AAD/8QAA/+wAAP/2AAAAAP/2AAAAAAAA/9MAAAAA/9gAAP/O/+z/2P/O/+z/9gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/sAAD/7AAA/9gAAP/YAAAAAAAA/5L/xP9+/90AAAAA/+z/7P/sAAD/9v+c/7oAAP/2AAAAAAAA/5L/2P9+/5f/fv+w/9j/l/+c/7X/7P/s/7UAAAAAAAAAAAAAAAAAAP+cAAD/kv/iAAD/tf/E/8n/uv/E/7AAAAAAAAD/2AAA//YAAAAAAAAAAAAAAAD/9gAA//EAAAAAAAAAAAAA/+cAAAAA/+wAAP/i//b/7P/sAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/s//EAAP/xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/8QAA/7UAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/90AAAAAAAAAAAAAAAAAAP/7AAAAAP/s/+wAAP/sAAAAAAAAAAAAAAAA//b/pgAAAAD/zgAA/7oAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/5wAAAAAAAAAAAAAAAAAAAAAAAAAAP/2AAAAAAAAAAAAAAAA/+wAAAAA//EAAAAAAAD/8QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/2AAAAAAAKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/8QAA/7r/8f/sAAAAAP/2AAD/9gAAAAAAAAAA//sAAAAAAAAAAP/i/90AAP/2AAAAAAAAAAAAAAAAAAAAAP/n/+z/4v/n//EAAAAAAAD/2AAAAAD/pv/xAAD/nAAA/5IAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/iAAAAAAAA/8QAAP/EAAAAAAAAAAD/7AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//EAAAAA//EAAAAAAAD/9gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/2AAAAAAAAAAAAAAAA//YAAP/2//YAAAAAAAD/7AAAAAAAAAAAAAAAAAAAAAAAAP/2AAAAAAAAAAAAAAAA/+wAAAAA/+wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/xAAAAAAAAAAAAAAAA/+wAAP/2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/9gAAAAA//EAAAAA//YAAAAAAAD/9v/2AAoAAAAAAAAAAP/x//EAAAAKAA8AAAAAAAAAAAAAAAAAAP/7//v/9v/7AAAAAAAAAAAAAAAAAAD/zgAA/+z/8QAA/9gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/2AAAAAD/nP/x/4j/nAAA/34AAAAAAAAAAAAAAAAAAAAA/+wAAAAA//YAAAAA//H/9gAAAAAAAAAPAAD/zgAAAAAAAAAA/9gAAAAA/+wAAP/nAAAAAP+r/7oAAP/TAAD/7AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/7AAA/7D/9v/sAAAAAP/2AAD/9gAAAAAAAAAAAAAAAAAAAAAAAP/i/9gAAAAAAAAAAAAAAAAAAAAAAAAAAP/n/+f/4v/n//EAAAAAAAD/2AAAAAD/nP/x/4j/nAAA/34AAAAAAAAAAAAAAAAAAAAA/+wAAAAA//YAAAAA//H/9gAAAAAAAAAAAAD/zgAAAAAAAAAA/9gAAAAA/+wAAP/nAAAAAP+r/7oAAP/EAAD/7AAA/9gAAAAAAAD/pgAA/9j/3f/O/7D/4gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/4gAAAAAAAAAAAAAAAAAA/9gAAAAA//YAAP/x//b/4v/x//YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/xAAAAHgAAAB4AHgAU//YAAP/T//b/0wAAAAD/9v/xAAAAAAAAAAAAAAAeACMAAAAeACMANwAAAAD/0wAAAAAAAAAAAAAAAAAA//YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/84AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/ugAA/9j/3f/s/7UAAAAAAAAAAAAAAAAAAAAA//YAAAAA//sAAAAAAAD/+wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/x//b/8f/xAAAAAAAA/+wAAAAA//b/pgAA/8T/zv/O/5z/8QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/2AAAAAP/2AAAAAP/i/+z/0//i/+wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/8QAA/7UAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/+IAAAAAAAAAAAAAAAAAAAAAAAAAAP/s//EAAP/xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/2AAAAAAAA/9gAAAAA/+cAAAAA/+cAAP/sAAD/5//s//YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/2AAD/9v/s/+wAAP/xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/2AAD/9gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/7AAA/7D/8f/sAAAAAP/sAAD/7AAAAAAAAAAA//YAAAAAAAAAAP/i/84AAP/sAAAAAAAAAAAAAAAAAAAAAP/i/+f/3f/i/+wAAAAAAAD/4gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/+IAAAAA/+IAAAAAAAD/7AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/7AAAAAD/xP/xAAD/zgAA/7oAAAAKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/xAAAAAAAA/90AAP/dAAAAAAAA/6YAAP+wAAAAAAAAAAAAAAAAAAAAAP/2AAAAAAAAAAAAAAAA//EAAAAA//EAAAAAAAD/8QAAAAAAAAAAAAAAAAAAAAD/3QAAAAAAAP/2AAAAAAAPAAAAAAAAAAAAAAAA//YAAAAA/5wAAP+cAAAAAAAAAAAAAAAAAAAAAP/sAAAAAAAAAAAAAAAA/9MAAAAA/9gAAAAAAAD/2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/iAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/nAAAAFAAA/+IAAAAA/+cAAP+m/+f/pgAAAAD/5//2AAAAAAAAAAAAAAAAAAAAAAAUACMAAAAAAAD/tQAAAAAAAAAAAAAAAAAA//YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/7X/9v/xAAAAAAAAAAAAAAAAAAAAAP/2AAAAAAAAAAAAAP/s/90AAP/2AAAAAP/2AAAAAP/2AAAAAP/s//H/5//x//YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP+cAAD/nP/iAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/4j/2AAA/+IAAAAAAAAAAAAAAAD/7P+/AAAAAAAAAAAAAAAA/7AAAAAA/7oAAAAA/+f/ugAAAAAAAAAA/84AAAAAAAAAAAAAAAAAAP+rAAAAAP/sAAD/zgAA/84AAP/O/8QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/9gAAAAA//EAAAAA//EAAAAAAAD/8f/2AAAAAAAAAAAAAAAAAAAAAAAAAAoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/84AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/nAAAAAAAAAAAAAAAA/+IAAP+r/+f/q//xAAD/5//i//EAAAAAAAAAAAAAAAAAAAAAAAAAAP/sAAAAAAAAAAAAAAAA//EAAP/x//sAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/sAAAAAAAA/87/9v/s/+cAAP+6/+z/uv/2AAD/7P/s//YAAAAAAAAAAAAA//YAAAAAAAAAAP/xAAD/xAAAAAAAAP/x//b/9v/2//sAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/xAAAAAAAAAAAAAAAA/90AAAAA/+IAAP/iAAD/4v/T//EAAAAAAAAAAAAAAAAAAAAAAAAAAP/sAAAAAAAAAAAAAAAA//YAAP/2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/nAAAAAAAA/87/9v/s/+IAAP+r/+f/q//xAAD/5//i//EAAAAAAAAAAAAA//YAAAAAAAAAAP/sAAD/ugAAAAAAAP/x//b/9v/2//sAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/9MAAAAA//EAAAAA//EAAAAAAAD/8f/xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/sAAD/7AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAcAWwAYAAAALAAAABkAAAAgACMAIgAzAAAAMgAfAB8AAAAAAAAAAAABAAIAAwAEAAYABwAIAAkACgAAAAsADAANAA4ADwAQABEAEgATABQAFQAWAB0AGwAAAAAAFwAaAB4AIQAkACUAKAAAAAAAKQAAACgAKAArABoAAAA0ADYAOAA5ABwAAAAAAAAAAAAAAAAAAAAmAAAAAAAAAAAAJwAtACMAIwAuAC8AIAAuAC8AIAAAACIAJgAnAAEABwBdAA0AAAAAACEADgAAABUAGAAXACkAAAAoABQAFAAAAAAAAAAiAAEAAAACAAAAAAACAAMAAAAAAAAAAgAAAAIAAAAEAAUABgAHAAgACQAKAAsAAAAQABIAAAAMAA8AEwATABkAGgAPAB0AHgAPAA8AHwAfABMAHwAWACoALQAvADAAAAAAABEAAAAAAAAAAAAAABsAJgAAAAAAAAAcACMAGAAYACQAJQAVACQAJQAVAAAAFwAbABwAAAAmAAIADgAHAAcAAAAJAAkAAQALAAsAAgANABAAAwASABQABwAZACEACgAjADAAEwAzADkAIQA8ADwAKAA+AEEAKQBDAEcALQBPAE8AMgBUAF0AMwBfAGEAPQABAAgAAQAAAAEAAQADAAAAAQAAAAoAMAA+AAJERkxUAA5sYXRuABoABAAAAAD//wABAAAABAAAAAD//wABAAAAAXNzMDEACAAAAAEAAAACAAYADgAGAAAAAQAQAAEAAAABACgAAQAIAAEADgABAAEAZAABAAQAAQBkAAEAAAABAAAAAQABAAb/nwABAAEAZA==); font-weight:300; font-style:normal; } @font-face{ font-family: "Gotham Rounded B"; src: url(data:font/truetype;base64,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cmVlbWVudCB0aGF0IGV4aXN0cyBiZXR3ZWVuIHlvdSBhbmQgSG9lZmxlciAmIENvLiBJZiBubyBzdWNoIGFncmVlbWVudCBleGlzdHMsIHlvdSBtYXkgbm90IHVzZSB0aGlzIHNvZnR3YXJlIGZvciBhbnkgcHVycG9zZS4gRm9yIG1vcmUgaW5mb3JtYXRpb24sIHBsZWFzZSB2aXNpdCBodHRwOi8vd3d3LnR5cG9ncmFwaHkuY29tL3dlYmZvbnQtc29mdHdhcmUsIG9yIGNvbnRhY3QgSG9lZmxlciAmIENvLiBhdCB3d3cudHlwb2dyYXBoeS5jb20gMTcxMjQ3LTg4NDc0LTIwMTUwNjIzLTI0MjMtMTQwMjE5d3d3LnR5cG9ncmFwaHkuY29taHR0cDovL3d3dy50eXBvZ3JhcGh5LmNvbS93ZWJmb250LXNvZnR3YXJlAEMAbwBwAHkAcgBpAGcAaAB0ACAAKABDACkAIAAyADAAMAA2ACwAIAAyADAAMAA3ACAASABvAGUAZgBsAGUAcgAgACYAIABDAG8ALgAgAGgAdAB0AHAAOgAvAC8AdwB3AHcALgB0AHkAcABvAGcAcgBhAHAAaAB5AC4AYwBvAG0AQwBvAHAAeQByAGkAZwBoAHQAIAAoAEMAKQAgAEgAJgBDAG8AIAB8ACAAdAB5AHAAbwBnAHIAYQBwAGgAeQAuAGMAbwBtAFIAZQBnAHUAbABhAHIAMQA3ADEAMgA0ADcALQA4ADgANAA3ADQALQAyADAAMQA1ADAANgAyADMALQAyADQAMgAzAC0AMQA0ADAAMgAxADkAVgBlAHIAcwBpAG8AbgAgADEALgAzADAAMQBGAG8AbgB0AEcAbwB0AGgAYQBtACAAaQBzACAAYQAgAHQAcgBhAGQAZQBtAGEAcgBrACAAbwBmACAASABvAGUAZgBsAGUAcgAgACYAIABDAG8ALgAsACAAdwBoAGkAYwBoACAAbQBhAHkAIABiAGUAIAByAGUAZwBpAHMAdABlAHIAZQBkACAAaQBuACAAYwBlAHIAdABhAGkAbgAgAGoAdQByAGkAcwBkAGkAYwB0AGkAbwBuAHMALgBIAG8AZQBmAGwAZQByACAAJgAgAEMAbwAuAFQAaABpAHMAIABzAG8AZgB0AHcAYQByAGUAIABpAHMAIAB0AGgAZQAgAHAAcgBvAHAAZQByAHQAeQAgAG8AZgAgAEgAbwBlAGYAbABlAHIAIAAmACAAQwBvAC4AIABZAG8AdQAgAG0AYQB5ACAAbgBvAHQAIABjAG8AcAB5ACwAIABtAG8AZABpAGYAeQAsACAAZABpAHMAdAByAGkAYgB1AHQAZQAsACAAbwByACAAZABvAHcAbgBsAG8AYQBkACAAdABoAGkAcwAgAHMAbwBmAHQAdwBhAHIAZQAsACAAbwByACAAaQBuAHMAdABhAGwAbAAgAGkAdAAgAHUAcABvAG4AIABhAG4AeQAgAGMAbwBtAHAAdQB0AGUAcgAsACAAbwByACAAaABvAHMAdAAgAGkAdAAgAGYAcgBvAG0AIABhAG4AeQAgAGwAbwBjAGEAdABpAG8AbgAuACAAWQBvAHUAcgAgAHIAaQBnAGgAdAAgAHQAbwAgAHUAcwBlACAAdABoAGkAcwAgAHMAbwBmAHQAdwBhAHIAZQAgAGkAcwAgAHMAdQBiAGoAZQBjAHQAIAB0AG8AIAB0AGgAZQAgAFQAZQByAG0AcwAgAG8AZgAgAFMAZQByAHYAaQBjAGUAIABhAGcAcgBlAGUAbQBlAG4AdAAgAHQAaABhAHQAIABlAHgAaQBzAHQAcwAgAGIAZQB0AHcAZQBlAG4AIAB5AG8AdQAgAGEAbgBkACAASABvAGUAZgBsAGUAcgAgACYAIABDAG8ALgAgAEkAZgAgAG4AbwAgAHMAdQBjAGgAIABhAGcAcgBlAGUAbQBlAG4AdAAgAGUAeABpAHMAdABzACwAIAB5AG8AdQAgAG0AYQB5ACAAbgBvAHQAIAB1AHMAZQAgAHQAaABpAHMAIABzAG8AZgB0AHcAYQByAGUAIABmAG8AcgAgAGEAbgB5ACAAcAB1AHIAcABvAHMAZQAuACAARgBvAHIAIABtAG8AcgBlACAAaQBuAGYAbwByAG0AYQB0AGkAbwBuACwAIABwAGwAZQBhAHMAZQAgAHYAaQBzAGkAdAAgAGgAdAB0AHAAOgAvAC8AdwB3AHcALgB0AHkAcABvAGcAcgBhAHAAaAB5AC4AYwBvAG0ALwB3AGUAYgBmAG8AbgB0AC0AcwBvAGYAdAB3AGEAcgBlACwAIABvAHIAIABjAG8AbgB0AGEAYwB0ACAASABvAGUAZgBsAGUAcgAgACYAIABDAG8ALgAgAGEAdAAgAHcAdwB3AC4AdAB5AHAAbwBnAHIAYQBwAGgAeQAuAGMAbwBtACAAMQA3ADEAMgA0ADcALQA4ADgANAA3ADQALQAyADAAMQA1ADAANgAyADMALQAyADQAMgAzAC0AMQA0ADAAMgAxADkAdwB3AHcALgB0AHkAcABvAGcAcgBhAHAAaAB5AC4AYwBvAG0AaAB0AHQAcAA6AC8ALwB3AHcAdwAuAHQAeQBwAG8AZwByAGEAcABoAHkALgBjAG8AbQAvAHcAZQBiAGYAbwBuAHQALQBzAG8AZgB0AHcAYQByAGUAAAIAAAAAAAD/tQAyAAAAAAAAAAAAAAAAAAAAAAAAAAAAHQAAAAEAAgADAAQABwATABQAFQAWABgAGQAbABwAIwAoACsALAAxADsARwBSAFUAVgBYAFoAXQCjAQIHaGNvc2x1ZwABAAH//wAKAAEAAAAOAAAAGAAAAAAAAgABAAEAHAABAAQAAAACAAA=); font-weight:300; font-style:normal; } \ No newline at end of file diff --git a/docs/static/fonts/332720/F0E469574253DABD5.css b/docs/static/fonts/332720/F0E469574253DABD5.css deleted file mode 100644 index fc6add2211..0000000000 --- a/docs/static/fonts/332720/F0E469574253DABD5.css +++ /dev/null @@ -1,19 +0,0 @@ - -/* - Copyright (C) 2011-2015 Hoefler & Co. - This software is the property of Hoefler & Co. (H&Co). - Your right to access and use this software is subject to the - applicable License Agreement, or Terms of Service, that exists - between you and H&Co. If no such agreement exists, you may not - access or use this software for any purpose. - This software may only be hosted at the locations specified in - the applicable License Agreement or Terms of Service, and only - for the purposes expressly set forth therein. You may not copy, - modify, convert, create derivative works from or distribute this - software in any way, or make it accessible to any third party, - without first obtaining the written permission of H&Co. - For more information, please visit us at http://typography.com. - 171247-88474-20150623 -*/ - -@font-face{ font-family: "Gotham Rounded A"; src: url(data:application/x-font-woff;base64,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); font-weight:300; font-style:normal; } @font-face{ font-family: "Gotham Rounded B"; src: url(data:application/x-font-woff;base64,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); font-weight:300; font-style:normal; } \ No newline at end of file diff --git a/docs/static/fonts/332720/FA4DC96C390FF844F.eot b/docs/static/fonts/332720/FA4DC96C390FF844F.eot deleted file mode 100644 index 0a1e78dcad..0000000000 Binary files a/docs/static/fonts/332720/FA4DC96C390FF844F.eot and /dev/null differ diff --git a/docs/static/images/Mercurial_features_screenshot.png b/docs/static/images/Mercurial_features_screenshot.png deleted file mode 100644 index 77370d6df9..0000000000 Binary files a/docs/static/images/Mercurial_features_screenshot.png and /dev/null differ diff --git a/docs/static/images/blog/nuclide-atom-settings.png b/docs/static/images/blog/nuclide-atom-settings.png deleted file mode 100644 index 0e6e57dea9..0000000000 Binary files a/docs/static/images/blog/nuclide-atom-settings.png and /dev/null differ diff --git a/docs/static/images/blog/nuclide-feature-settings.png b/docs/static/images/blog/nuclide-feature-settings.png deleted file mode 100644 index 2ec10785c8..0000000000 Binary files a/docs/static/images/blog/nuclide-feature-settings.png and /dev/null differ diff --git a/docs/static/images/docs/editor-basics-adding-projects.png b/docs/static/images/docs/editor-basics-adding-projects.png deleted file mode 100644 index af90987b96..0000000000 Binary files a/docs/static/images/docs/editor-basics-adding-projects.png and /dev/null differ diff --git a/docs/static/images/docs/editor-basics-command-palette-intro.png b/docs/static/images/docs/editor-basics-command-palette-intro.png deleted file mode 100644 index 4952eac8b4..0000000000 Binary files a/docs/static/images/docs/editor-basics-command-palette-intro.png and /dev/null differ diff --git a/docs/static/images/docs/editor-basics-command-palette-search.png b/docs/static/images/docs/editor-basics-command-palette-search.png deleted file mode 100644 index 7d584fd811..0000000000 Binary files a/docs/static/images/docs/editor-basics-command-palette-search.png and /dev/null differ diff --git a/docs/static/images/docs/editor-basics-distraction-free.png b/docs/static/images/docs/editor-basics-distraction-free.png deleted file mode 100644 index daba559d09..0000000000 Binary files a/docs/static/images/docs/editor-basics-distraction-free.png and /dev/null differ diff --git a/docs/static/images/docs/editor-basics-distraction.png b/docs/static/images/docs/editor-basics-distraction.png deleted file mode 100644 index 8e788441da..0000000000 Binary files a/docs/static/images/docs/editor-basics-distraction.png and /dev/null differ diff --git a/docs/static/images/docs/editor-basics-editing-area-symbols.png b/docs/static/images/docs/editor-basics-editing-area-symbols.png deleted file mode 100644 index abe4126038..0000000000 Binary files a/docs/static/images/docs/editor-basics-editing-area-symbols.png and /dev/null differ diff --git a/docs/static/images/docs/editor-basics-editing-context-aware.png b/docs/static/images/docs/editor-basics-editing-context-aware.png deleted file mode 100644 index 9687ffaf8b..0000000000 Binary files a/docs/static/images/docs/editor-basics-editing-context-aware.png and /dev/null differ diff --git a/docs/static/images/docs/editor-basics-editing-omnisearch.png b/docs/static/images/docs/editor-basics-editing-omnisearch.png deleted file mode 100644 index e7eb5e70ad..0000000000 Binary files a/docs/static/images/docs/editor-basics-editing-omnisearch.png and /dev/null differ diff --git a/docs/static/images/docs/editor-basics-editing-panes.png b/docs/static/images/docs/editor-basics-editing-panes.png deleted file mode 100644 index f1b8d5de38..0000000000 Binary files a/docs/static/images/docs/editor-basics-editing-panes.png and /dev/null differ diff --git a/docs/static/images/docs/editor-basics-explorer-changed-files.png b/docs/static/images/docs/editor-basics-explorer-changed-files.png deleted file mode 100644 index 2bd783f3a5..0000000000 Binary files a/docs/static/images/docs/editor-basics-explorer-changed-files.png and /dev/null differ diff --git a/docs/static/images/docs/editor-basics-explorer-context-aware.png b/docs/static/images/docs/editor-basics-explorer-context-aware.png deleted file mode 100644 index 6318df42cd..0000000000 Binary files a/docs/static/images/docs/editor-basics-explorer-context-aware.png and /dev/null differ diff --git a/docs/static/images/docs/editor-basics-file-tree.png b/docs/static/images/docs/editor-basics-file-tree.png deleted file mode 100644 index 9116f66734..0000000000 Binary files a/docs/static/images/docs/editor-basics-file-tree.png and /dev/null differ diff --git a/docs/static/images/docs/editor-basics-gutter-code-diagnostics.png b/docs/static/images/docs/editor-basics-gutter-code-diagnostics.png deleted file mode 100644 index d8e5e29659..0000000000 Binary files a/docs/static/images/docs/editor-basics-gutter-code-diagnostics.png and /dev/null differ diff --git a/docs/static/images/docs/editor-basics-gutter-intro.png b/docs/static/images/docs/editor-basics-gutter-intro.png deleted file mode 100644 index c27ed858f1..0000000000 Binary files a/docs/static/images/docs/editor-basics-gutter-intro.png and /dev/null differ diff --git a/docs/static/images/docs/editor-basics-homepage.png b/docs/static/images/docs/editor-basics-homepage.png deleted file mode 100644 index 20d6c18d2b..0000000000 Binary files a/docs/static/images/docs/editor-basics-homepage.png and /dev/null differ diff --git a/docs/static/images/docs/editor-basics-intro.png b/docs/static/images/docs/editor-basics-intro.png deleted file mode 100644 index 6df564c953..0000000000 Binary files a/docs/static/images/docs/editor-basics-intro.png and /dev/null differ diff --git a/docs/static/images/docs/editor-basics-nuclide-package.png b/docs/static/images/docs/editor-basics-nuclide-package.png deleted file mode 100644 index 6af69e0731..0000000000 Binary files a/docs/static/images/docs/editor-basics-nuclide-package.png and /dev/null differ diff --git a/docs/static/images/docs/editor-basics-nuclide-preferences.png b/docs/static/images/docs/editor-basics-nuclide-preferences.png deleted file mode 100644 index 6e5db93619..0000000000 Binary files a/docs/static/images/docs/editor-basics-nuclide-preferences.png and /dev/null differ diff --git a/docs/static/images/docs/editor-basics-open-files.png b/docs/static/images/docs/editor-basics-open-files.png deleted file mode 100644 index 27f68cea00..0000000000 Binary files a/docs/static/images/docs/editor-basics-open-files.png and /dev/null differ diff --git a/docs/static/images/docs/editor-basics-status-bar-connection.png b/docs/static/images/docs/editor-basics-status-bar-connection.png deleted file mode 100644 index 7c8f28c770..0000000000 Binary files a/docs/static/images/docs/editor-basics-status-bar-connection.png and /dev/null differ diff --git a/docs/static/images/docs/editor-basics-status-bar-diagnostics.png b/docs/static/images/docs/editor-basics-status-bar-diagnostics.png deleted file mode 100644 index 2f379c44b1..0000000000 Binary files a/docs/static/images/docs/editor-basics-status-bar-diagnostics.png and /dev/null differ diff --git a/docs/static/images/docs/editor-basics-status-bar-intro.png b/docs/static/images/docs/editor-basics-status-bar-intro.png deleted file mode 100644 index 1f36158c53..0000000000 Binary files a/docs/static/images/docs/editor-basics-status-bar-intro.png and /dev/null differ diff --git a/docs/static/images/docs/editor-basics-uncommitted.png b/docs/static/images/docs/editor-basics-uncommitted.png deleted file mode 100644 index 2f3c7a518e..0000000000 Binary files a/docs/static/images/docs/editor-basics-uncommitted.png and /dev/null differ diff --git a/docs/static/images/docs/editor-keyboard-shortcuts-hyperclick.png b/docs/static/images/docs/editor-keyboard-shortcuts-hyperclick.png deleted file mode 100644 index b72e071d00..0000000000 Binary files a/docs/static/images/docs/editor-keyboard-shortcuts-hyperclick.png and /dev/null differ diff --git a/docs/static/images/docs/editor-setup-atom-install-nuclide.png b/docs/static/images/docs/editor-setup-atom-install-nuclide.png deleted file mode 100644 index 58d6d7b189..0000000000 Binary files a/docs/static/images/docs/editor-setup-atom-install-nuclide.png and /dev/null differ diff --git a/docs/static/images/docs/editor-setup-atom-install-windows.png b/docs/static/images/docs/editor-setup-atom-install-windows.png deleted file mode 100644 index 921dac3ec0..0000000000 Binary files a/docs/static/images/docs/editor-setup-atom-install-windows.png and /dev/null differ diff --git a/docs/static/images/docs/editor-setup-recommended-packages.png b/docs/static/images/docs/editor-setup-recommended-packages.png deleted file mode 100644 index 0692f4d8ec..0000000000 Binary files a/docs/static/images/docs/editor-setup-recommended-packages.png and /dev/null differ diff --git a/docs/static/images/docs/editor-uninstall-reenable-atom-tree-view.png b/docs/static/images/docs/editor-uninstall-reenable-atom-tree-view.png deleted file mode 100644 index 4f2679ea21..0000000000 Binary files a/docs/static/images/docs/editor-uninstall-reenable-atom-tree-view.png and /dev/null differ diff --git a/docs/static/images/docs/feature-buck-command-palette.png b/docs/static/images/docs/feature-buck-command-palette.png deleted file mode 100644 index 4bd7df76f6..0000000000 Binary files a/docs/static/images/docs/feature-buck-command-palette.png and /dev/null differ diff --git a/docs/static/images/docs/feature-buck-nuclide-menu.png b/docs/static/images/docs/feature-buck-nuclide-menu.png deleted file mode 100644 index 7d9261f3c6..0000000000 Binary files a/docs/static/images/docs/feature-buck-nuclide-menu.png and /dev/null differ diff --git a/docs/static/images/docs/feature-buck-task-runner.png b/docs/static/images/docs/feature-buck-task-runner.png deleted file mode 100644 index 0ba34a0b09..0000000000 Binary files a/docs/static/images/docs/feature-buck-task-runner.png and /dev/null differ diff --git a/docs/static/images/docs/feature-context-view-highlight.png b/docs/static/images/docs/feature-context-view-highlight.png deleted file mode 100644 index 2e44f19f37..0000000000 Binary files a/docs/static/images/docs/feature-context-view-highlight.png and /dev/null differ diff --git a/docs/static/images/docs/feature-context-view.png b/docs/static/images/docs/feature-context-view.png deleted file mode 100644 index df8dfe7656..0000000000 Binary files a/docs/static/images/docs/feature-context-view.png and /dev/null differ diff --git a/docs/static/images/docs/feature-debugger-basics-attach-target-process.png b/docs/static/images/docs/feature-debugger-basics-attach-target-process.png deleted file mode 100644 index c67761fc2d..0000000000 Binary files a/docs/static/images/docs/feature-debugger-basics-attach-target-process.png and /dev/null differ diff --git a/docs/static/images/docs/feature-debugger-basics-breakpoint-menu.png b/docs/static/images/docs/feature-debugger-basics-breakpoint-menu.png deleted file mode 100644 index 6baab0953a..0000000000 Binary files a/docs/static/images/docs/feature-debugger-basics-breakpoint-menu.png and /dev/null differ diff --git a/docs/static/images/docs/feature-debugger-basics-breakpoints-debugger-controls.png b/docs/static/images/docs/feature-debugger-basics-breakpoints-debugger-controls.png deleted file mode 100644 index 7ee0489d67..0000000000 Binary files a/docs/static/images/docs/feature-debugger-basics-breakpoints-debugger-controls.png and /dev/null differ diff --git a/docs/static/images/docs/feature-debugger-basics-breakpoints-gutter.png b/docs/static/images/docs/feature-debugger-basics-breakpoints-gutter.png deleted file mode 100644 index 278fc5bc88..0000000000 Binary files a/docs/static/images/docs/feature-debugger-basics-breakpoints-gutter.png and /dev/null differ diff --git a/docs/static/images/docs/feature-debugger-basics-breakpoints-main-debugging-tab.png b/docs/static/images/docs/feature-debugger-basics-breakpoints-main-debugging-tab.png deleted file mode 100644 index f5f235ca0b..0000000000 Binary files a/docs/static/images/docs/feature-debugger-basics-breakpoints-main-debugging-tab.png and /dev/null differ diff --git a/docs/static/images/docs/feature-debugger-basics-breakpoints-set.png b/docs/static/images/docs/feature-debugger-basics-breakpoints-set.png deleted file mode 100644 index 60a057ca40..0000000000 Binary files a/docs/static/images/docs/feature-debugger-basics-breakpoints-set.png and /dev/null differ diff --git a/docs/static/images/docs/feature-debugger-basics-debugger-breakpoint-menu.png b/docs/static/images/docs/feature-debugger-basics-debugger-breakpoint-menu.png deleted file mode 100644 index 06a865b8d6..0000000000 Binary files a/docs/static/images/docs/feature-debugger-basics-debugger-breakpoint-menu.png and /dev/null differ diff --git a/docs/static/images/docs/feature-debugger-basics-debugger-detach.png b/docs/static/images/docs/feature-debugger-basics-debugger-detach.png deleted file mode 100644 index 681835be9b..0000000000 Binary files a/docs/static/images/docs/feature-debugger-basics-debugger-detach.png and /dev/null differ diff --git a/docs/static/images/docs/feature-debugger-basics-debugger-example.png b/docs/static/images/docs/feature-debugger-basics-debugger-example.png deleted file mode 100644 index 16141c8e0c..0000000000 Binary files a/docs/static/images/docs/feature-debugger-basics-debugger-example.png and /dev/null differ diff --git a/docs/static/images/docs/feature-debugger-basics-debugger-watch-menu.png b/docs/static/images/docs/feature-debugger-basics-debugger-watch-menu.png deleted file mode 100644 index d20f8cbd06..0000000000 Binary files a/docs/static/images/docs/feature-debugger-basics-debugger-watch-menu.png and /dev/null differ diff --git a/docs/static/images/docs/feature-debugger-basics-debugger-web-inspector.png b/docs/static/images/docs/feature-debugger-basics-debugger-web-inspector.png deleted file mode 100644 index dee43c005f..0000000000 Binary files a/docs/static/images/docs/feature-debugger-basics-debugger-web-inspector.png and /dev/null differ diff --git a/docs/static/images/docs/feature-debugger-basics-detach.png b/docs/static/images/docs/feature-debugger-basics-detach.png deleted file mode 100644 index 68511617e0..0000000000 Binary files a/docs/static/images/docs/feature-debugger-basics-detach.png and /dev/null differ diff --git a/docs/static/images/docs/feature-debugger-basics-stepping-example-start-other-module.png b/docs/static/images/docs/feature-debugger-basics-stepping-example-start-other-module.png deleted file mode 100644 index a911da3d11..0000000000 Binary files a/docs/static/images/docs/feature-debugger-basics-stepping-example-start-other-module.png and /dev/null differ diff --git a/docs/static/images/docs/feature-debugger-basics-stepping-icons.png b/docs/static/images/docs/feature-debugger-basics-stepping-icons.png deleted file mode 100644 index 4faba70c19..0000000000 Binary files a/docs/static/images/docs/feature-debugger-basics-stepping-icons.png and /dev/null differ diff --git a/docs/static/images/docs/feature-debugger-basics-target-after-attach.png b/docs/static/images/docs/feature-debugger-basics-target-after-attach.png deleted file mode 100644 index 668258d723..0000000000 Binary files a/docs/static/images/docs/feature-debugger-basics-target-after-attach.png and /dev/null differ diff --git a/docs/static/images/docs/feature-debugger-basics-target-process.png b/docs/static/images/docs/feature-debugger-basics-target-process.png deleted file mode 100644 index 53aa35e975..0000000000 Binary files a/docs/static/images/docs/feature-debugger-basics-target-process.png and /dev/null differ diff --git a/docs/static/images/docs/feature-debugger-basics-webinspector.png b/docs/static/images/docs/feature-debugger-basics-webinspector.png deleted file mode 100644 index 26c6053562..0000000000 Binary files a/docs/static/images/docs/feature-debugger-basics-webinspector.png and /dev/null differ diff --git a/docs/static/images/docs/feature-debugger-evaluation-ex.png b/docs/static/images/docs/feature-debugger-evaluation-ex.png deleted file mode 100644 index 8b9ddddfaf..0000000000 Binary files a/docs/static/images/docs/feature-debugger-evaluation-ex.png and /dev/null differ diff --git a/docs/static/images/docs/feature-debugger-languages-cpp-attach.png b/docs/static/images/docs/feature-debugger-languages-cpp-attach.png deleted file mode 100644 index 3ca5355614..0000000000 Binary files a/docs/static/images/docs/feature-debugger-languages-cpp-attach.png and /dev/null differ diff --git a/docs/static/images/docs/feature-debugger-languages-cpp-launch.png b/docs/static/images/docs/feature-debugger-languages-cpp-launch.png deleted file mode 100644 index 0c768c491a..0000000000 Binary files a/docs/static/images/docs/feature-debugger-languages-cpp-launch.png and /dev/null differ diff --git a/docs/static/images/docs/feature-debugger-languages-hack-php-filtering.png b/docs/static/images/docs/feature-debugger-languages-hack-php-filtering.png deleted file mode 100644 index 1e98701486..0000000000 Binary files a/docs/static/images/docs/feature-debugger-languages-hack-php-filtering.png and /dev/null differ diff --git a/docs/static/images/docs/feature-debugger-languages-react-native-application-debug-options.png b/docs/static/images/docs/feature-debugger-languages-react-native-application-debug-options.png deleted file mode 100644 index 305a289b5f..0000000000 Binary files a/docs/static/images/docs/feature-debugger-languages-react-native-application-debug-options.png and /dev/null differ diff --git a/docs/static/images/docs/feature-debugger-languages-react-native-application-show-inspector.png b/docs/static/images/docs/feature-debugger-languages-react-native-application-show-inspector.png deleted file mode 100644 index d323ee9d19..0000000000 Binary files a/docs/static/images/docs/feature-debugger-languages-react-native-application-show-inspector.png and /dev/null differ diff --git a/docs/static/images/docs/feature-debugger-languages-react-native-debugging.png b/docs/static/images/docs/feature-debugger-languages-react-native-debugging.png deleted file mode 100644 index 07ab48ed89..0000000000 Binary files a/docs/static/images/docs/feature-debugger-languages-react-native-debugging.png and /dev/null differ diff --git a/docs/static/images/docs/feature-debugger-languages-react-native-server.png b/docs/static/images/docs/feature-debugger-languages-react-native-server.png deleted file mode 100644 index 44022660bf..0000000000 Binary files a/docs/static/images/docs/feature-debugger-languages-react-native-server.png and /dev/null differ diff --git a/docs/static/images/docs/feature-debugger-selection-attach-server.png b/docs/static/images/docs/feature-debugger-selection-attach-server.png deleted file mode 100644 index aa91e98dfc..0000000000 Binary files a/docs/static/images/docs/feature-debugger-selection-attach-server.png and /dev/null differ diff --git a/docs/static/images/docs/feature-debugger-stepping-controls.png b/docs/static/images/docs/feature-debugger-stepping-controls.png deleted file mode 100644 index 0574671771..0000000000 Binary files a/docs/static/images/docs/feature-debugger-stepping-controls.png and /dev/null differ diff --git a/docs/static/images/docs/feature-debugger-stepping-line22-ex.png b/docs/static/images/docs/feature-debugger-stepping-line22-ex.png deleted file mode 100644 index 02e96fce49..0000000000 Binary files a/docs/static/images/docs/feature-debugger-stepping-line22-ex.png and /dev/null differ diff --git a/docs/static/images/docs/feature-debugger-stepping-other-module-ex.png b/docs/static/images/docs/feature-debugger-stepping-other-module-ex.png deleted file mode 100644 index 27ff1b0531..0000000000 Binary files a/docs/static/images/docs/feature-debugger-stepping-other-module-ex.png and /dev/null differ diff --git a/docs/static/images/docs/feature-debugger-stepping-stepin-ex.png b/docs/static/images/docs/feature-debugger-stepping-stepin-ex.png deleted file mode 100644 index aec3d1e3ef..0000000000 Binary files a/docs/static/images/docs/feature-debugger-stepping-stepin-ex.png and /dev/null differ diff --git a/docs/static/images/docs/feature-debugger-stepping-stepover-ex.png b/docs/static/images/docs/feature-debugger-stepping-stepover-ex.png deleted file mode 100644 index bd6839fc46..0000000000 Binary files a/docs/static/images/docs/feature-debugger-stepping-stepover-ex.png and /dev/null differ diff --git a/docs/static/images/docs/feature-debugger-target-attach.png b/docs/static/images/docs/feature-debugger-target-attach.png deleted file mode 100644 index 37c8f28881..0000000000 Binary files a/docs/static/images/docs/feature-debugger-target-attach.png and /dev/null differ diff --git a/docs/static/images/docs/feature-debugger-watches-ex.png b/docs/static/images/docs/feature-debugger-watches-ex.png deleted file mode 100644 index a2fcfead19..0000000000 Binary files a/docs/static/images/docs/feature-debugger-watches-ex.png and /dev/null differ diff --git a/docs/static/images/docs/feature-format-js-after.png b/docs/static/images/docs/feature-format-js-after.png deleted file mode 100644 index 2a75555410..0000000000 Binary files a/docs/static/images/docs/feature-format-js-after.png and /dev/null differ diff --git a/docs/static/images/docs/feature-format-js-before.png b/docs/static/images/docs/feature-format-js-before.png deleted file mode 100644 index 2dcc8a66a5..0000000000 Binary files a/docs/static/images/docs/feature-format-js-before.png and /dev/null differ diff --git a/docs/static/images/docs/feature-format-js-keybindings.png b/docs/static/images/docs/feature-format-js-keybindings.png deleted file mode 100644 index c0be428aba..0000000000 Binary files a/docs/static/images/docs/feature-format-js-keybindings.png and /dev/null differ diff --git a/docs/static/images/docs/feature-format-js-settings.png b/docs/static/images/docs/feature-format-js-settings.png deleted file mode 100644 index df3e1dd080..0000000000 Binary files a/docs/static/images/docs/feature-format-js-settings.png and /dev/null differ diff --git a/docs/static/images/docs/feature-health-overview.png b/docs/static/images/docs/feature-health-overview.png deleted file mode 100644 index 5a91fbf4ae..0000000000 Binary files a/docs/static/images/docs/feature-health-overview.png and /dev/null differ diff --git a/docs/static/images/docs/feature-hg-blame-access.png b/docs/static/images/docs/feature-hg-blame-access.png deleted file mode 100644 index 7561ac24a8..0000000000 Binary files a/docs/static/images/docs/feature-hg-blame-access.png and /dev/null differ diff --git a/docs/static/images/docs/feature-hg-blame-gutter.png b/docs/static/images/docs/feature-hg-blame-gutter.png deleted file mode 100644 index b9b65c263f..0000000000 Binary files a/docs/static/images/docs/feature-hg-blame-gutter.png and /dev/null differ diff --git a/docs/static/images/docs/feature-hg-bookmark.png b/docs/static/images/docs/feature-hg-bookmark.png deleted file mode 100644 index 3fa97f87d7..0000000000 Binary files a/docs/static/images/docs/feature-hg-bookmark.png and /dev/null differ diff --git a/docs/static/images/docs/feature-hg-diff-view-access.png b/docs/static/images/docs/feature-hg-diff-view-access.png deleted file mode 100644 index 8eecb09985..0000000000 Binary files a/docs/static/images/docs/feature-hg-diff-view-access.png and /dev/null differ diff --git a/docs/static/images/docs/feature-hg-diff-view-actual.png b/docs/static/images/docs/feature-hg-diff-view-actual.png deleted file mode 100644 index 46b90b983a..0000000000 Binary files a/docs/static/images/docs/feature-hg-diff-view-actual.png and /dev/null differ diff --git a/docs/static/images/docs/feature-hg-diff-view-stacked.png b/docs/static/images/docs/feature-hg-diff-view-stacked.png deleted file mode 100644 index 9ea066c830..0000000000 Binary files a/docs/static/images/docs/feature-hg-diff-view-stacked.png and /dev/null differ diff --git a/docs/static/images/docs/feature-hg-file-tree-highlight.png b/docs/static/images/docs/feature-hg-file-tree-highlight.png deleted file mode 100644 index c4889ddcf1..0000000000 Binary files a/docs/static/images/docs/feature-hg-file-tree-highlight.png and /dev/null differ diff --git a/docs/static/images/docs/feature-hg-line-mod-gutter-setting.png b/docs/static/images/docs/feature-hg-line-mod-gutter-setting.png deleted file mode 100644 index 923ba42925..0000000000 Binary files a/docs/static/images/docs/feature-hg-line-mod-gutter-setting.png and /dev/null differ diff --git a/docs/static/images/docs/feature-hg-line-modifications.png b/docs/static/images/docs/feature-hg-line-modifications.png deleted file mode 100644 index 69b25c0b06..0000000000 Binary files a/docs/static/images/docs/feature-hg-line-modifications.png and /dev/null differ diff --git a/docs/static/images/docs/feature-hg-number-of-line-changes.png b/docs/static/images/docs/feature-hg-number-of-line-changes.png deleted file mode 100644 index e116ec2477..0000000000 Binary files a/docs/static/images/docs/feature-hg-number-of-line-changes.png and /dev/null differ diff --git a/docs/static/images/docs/feature-outline-view-click.png b/docs/static/images/docs/feature-outline-view-click.png deleted file mode 100644 index f87f1008b2..0000000000 Binary files a/docs/static/images/docs/feature-outline-view-click.png and /dev/null differ diff --git a/docs/static/images/docs/feature-outline-view.png b/docs/static/images/docs/feature-outline-view.png deleted file mode 100644 index e4009bd0b6..0000000000 Binary files a/docs/static/images/docs/feature-outline-view.png and /dev/null differ diff --git a/docs/static/images/docs/feature-quick-open-filenames.png b/docs/static/images/docs/feature-quick-open-filenames.png deleted file mode 100644 index 46e0ed0553..0000000000 Binary files a/docs/static/images/docs/feature-quick-open-filenames.png and /dev/null differ diff --git a/docs/static/images/docs/feature-quick-open-omnisearch.png b/docs/static/images/docs/feature-quick-open-omnisearch.png deleted file mode 100644 index c72658003c..0000000000 Binary files a/docs/static/images/docs/feature-quick-open-omnisearch.png and /dev/null differ diff --git a/docs/static/images/docs/feature-quick-open-open-files.png b/docs/static/images/docs/feature-quick-open-open-files.png deleted file mode 100644 index 45fba3ced2..0000000000 Binary files a/docs/static/images/docs/feature-quick-open-open-files.png and /dev/null differ diff --git a/docs/static/images/docs/feature-quick-open-toggle-hack-symbols.png b/docs/static/images/docs/feature-quick-open-toggle-hack-symbols.png deleted file mode 100644 index a2dec16ea3..0000000000 Binary files a/docs/static/images/docs/feature-quick-open-toggle-hack-symbols.png and /dev/null differ diff --git a/docs/static/images/docs/feature-quick-open-toggle-recent-files.png b/docs/static/images/docs/feature-quick-open-toggle-recent-files.png deleted file mode 100644 index d662d9aa62..0000000000 Binary files a/docs/static/images/docs/feature-quick-open-toggle-recent-files.png and /dev/null differ diff --git a/docs/static/images/docs/feature-quick-open-toggle-window.png b/docs/static/images/docs/feature-quick-open-toggle-window.png deleted file mode 100644 index 7a4c2f79cf..0000000000 Binary files a/docs/static/images/docs/feature-quick-open-toggle-window.png and /dev/null differ diff --git a/docs/static/images/docs/feature-remote-add-profile.png b/docs/static/images/docs/feature-remote-add-profile.png deleted file mode 100644 index 25b137026c..0000000000 Binary files a/docs/static/images/docs/feature-remote-add-profile.png and /dev/null differ diff --git a/docs/static/images/docs/feature-remote-add-remote-project-file-tree.png b/docs/static/images/docs/feature-remote-add-remote-project-file-tree.png deleted file mode 100644 index ada48c6376..0000000000 Binary files a/docs/static/images/docs/feature-remote-add-remote-project-file-tree.png and /dev/null differ diff --git a/docs/static/images/docs/feature-remote-connect-dialog-box.png b/docs/static/images/docs/feature-remote-connect-dialog-box.png deleted file mode 100644 index a40b9895fe..0000000000 Binary files a/docs/static/images/docs/feature-remote-connect-dialog-box.png and /dev/null differ diff --git a/docs/static/images/docs/feature-remote-connect-menu.png b/docs/static/images/docs/feature-remote-connect-menu.png deleted file mode 100644 index 024d9c9488..0000000000 Binary files a/docs/static/images/docs/feature-remote-connect-menu.png and /dev/null differ diff --git a/docs/static/images/docs/feature-remote-file-tree.png b/docs/static/images/docs/feature-remote-file-tree.png deleted file mode 100644 index e7b20ed475..0000000000 Binary files a/docs/static/images/docs/feature-remote-file-tree.png and /dev/null differ diff --git a/docs/static/images/docs/feature-remote-profiles.png b/docs/static/images/docs/feature-remote-profiles.png deleted file mode 100644 index ede1904050..0000000000 Binary files a/docs/static/images/docs/feature-remote-profiles.png and /dev/null differ diff --git a/docs/static/images/docs/feature-remote-projects-menu.png b/docs/static/images/docs/feature-remote-projects-menu.png deleted file mode 100644 index b4de9825ce..0000000000 Binary files a/docs/static/images/docs/feature-remote-projects-menu.png and /dev/null differ diff --git a/docs/static/images/docs/feature-task-runer-buck-build-console.png b/docs/static/images/docs/feature-task-runer-buck-build-console.png deleted file mode 100644 index 40c0e231f9..0000000000 Binary files a/docs/static/images/docs/feature-task-runer-buck-build-console.png and /dev/null differ diff --git a/docs/static/images/docs/feature-task-runner-buck-build-diagnostics.png b/docs/static/images/docs/feature-task-runner-buck-build-diagnostics.png deleted file mode 100644 index 71aa6bf5e8..0000000000 Binary files a/docs/static/images/docs/feature-task-runner-buck-build-diagnostics.png and /dev/null differ diff --git a/docs/static/images/docs/feature-task-runner-buck-build-settings.png b/docs/static/images/docs/feature-task-runner-buck-build-settings.png deleted file mode 100644 index bab7290a4a..0000000000 Binary files a/docs/static/images/docs/feature-task-runner-buck-build-settings.png and /dev/null differ diff --git a/docs/static/images/docs/feature-task-runner-buck-build.png b/docs/static/images/docs/feature-task-runner-buck-build.png deleted file mode 100644 index 95eadcfa5c..0000000000 Binary files a/docs/static/images/docs/feature-task-runner-buck-build.png and /dev/null differ diff --git a/docs/static/images/docs/feature-task-runner-buck-debug.png b/docs/static/images/docs/feature-task-runner-buck-debug.png deleted file mode 100644 index 60fa839f28..0000000000 Binary files a/docs/static/images/docs/feature-task-runner-buck-debug.png and /dev/null differ diff --git a/docs/static/images/docs/feature-task-runner-buck-run.png b/docs/static/images/docs/feature-task-runner-buck-run.png deleted file mode 100644 index e87a769868..0000000000 Binary files a/docs/static/images/docs/feature-task-runner-buck-run.png and /dev/null differ diff --git a/docs/static/images/docs/feature-task-runner-hack-selection.png b/docs/static/images/docs/feature-task-runner-hack-selection.png deleted file mode 100644 index bfd1fa424e..0000000000 Binary files a/docs/static/images/docs/feature-task-runner-hack-selection.png and /dev/null differ diff --git a/docs/static/images/docs/feature-task-runner-hack-toolbar.png b/docs/static/images/docs/feature-task-runner-hack-toolbar.png deleted file mode 100644 index 5a92585ee8..0000000000 Binary files a/docs/static/images/docs/feature-task-runner-hack-toolbar.png and /dev/null differ diff --git a/docs/static/images/docs/feature-task-runner-hhvm-debug.png b/docs/static/images/docs/feature-task-runner-hhvm-debug.png deleted file mode 100644 index 7a2ffa3884..0000000000 Binary files a/docs/static/images/docs/feature-task-runner-hhvm-debug.png and /dev/null differ diff --git a/docs/static/images/docs/feature-task-runner-swift-build-output.png b/docs/static/images/docs/feature-task-runner-swift-build-output.png deleted file mode 100644 index 84ab8c66a2..0000000000 Binary files a/docs/static/images/docs/feature-task-runner-swift-build-output.png and /dev/null differ diff --git a/docs/static/images/docs/feature-task-runner-swift-build-settings.png b/docs/static/images/docs/feature-task-runner-swift-build-settings.png deleted file mode 100644 index 01618796c0..0000000000 Binary files a/docs/static/images/docs/feature-task-runner-swift-build-settings.png and /dev/null differ diff --git a/docs/static/images/docs/feature-task-runner-swift-build-toolbar.png b/docs/static/images/docs/feature-task-runner-swift-build-toolbar.png deleted file mode 100644 index bfbd0f8b73..0000000000 Binary files a/docs/static/images/docs/feature-task-runner-swift-build-toolbar.png and /dev/null differ diff --git a/docs/static/images/docs/feature-task-runner-swift-test-output.png b/docs/static/images/docs/feature-task-runner-swift-test-output.png deleted file mode 100644 index 8d7b3c34ff..0000000000 Binary files a/docs/static/images/docs/feature-task-runner-swift-test-output.png and /dev/null differ diff --git a/docs/static/images/docs/feature-task-runner-swift-test-toolbar.png b/docs/static/images/docs/feature-task-runner-swift-test-toolbar.png deleted file mode 100644 index 2bc8e9ba48..0000000000 Binary files a/docs/static/images/docs/feature-task-runner-swift-test-toolbar.png and /dev/null differ diff --git a/docs/static/images/docs/feature-toolbar-button-console.png b/docs/static/images/docs/feature-toolbar-button-console.png deleted file mode 100644 index deafc72c26..0000000000 Binary files a/docs/static/images/docs/feature-toolbar-button-console.png and /dev/null differ diff --git a/docs/static/images/docs/feature-toolbar-button-context-view.png b/docs/static/images/docs/feature-toolbar-button-context-view.png deleted file mode 100644 index 36cdd45934..0000000000 Binary files a/docs/static/images/docs/feature-toolbar-button-context-view.png and /dev/null differ diff --git a/docs/static/images/docs/feature-toolbar-button-debugger.png b/docs/static/images/docs/feature-toolbar-button-debugger.png deleted file mode 100644 index a1f7d710e4..0000000000 Binary files a/docs/static/images/docs/feature-toolbar-button-debugger.png and /dev/null differ diff --git a/docs/static/images/docs/feature-toolbar-button-diagnostics.png b/docs/static/images/docs/feature-toolbar-button-diagnostics.png deleted file mode 100644 index 419cf63b6e..0000000000 Binary files a/docs/static/images/docs/feature-toolbar-button-diagnostics.png and /dev/null differ diff --git a/docs/static/images/docs/feature-toolbar-button-diff-view.png b/docs/static/images/docs/feature-toolbar-button-diff-view.png deleted file mode 100644 index 1db59b0eb3..0000000000 Binary files a/docs/static/images/docs/feature-toolbar-button-diff-view.png and /dev/null differ diff --git a/docs/static/images/docs/feature-toolbar-button-distraction-free-mode.png b/docs/static/images/docs/feature-toolbar-button-distraction-free-mode.png deleted file mode 100644 index 2b08f0cebc..0000000000 Binary files a/docs/static/images/docs/feature-toolbar-button-distraction-free-mode.png and /dev/null differ diff --git a/docs/static/images/docs/feature-toolbar-button-hhvm-toolbar.png b/docs/static/images/docs/feature-toolbar-button-hhvm-toolbar.png deleted file mode 100644 index 24a9324375..0000000000 Binary files a/docs/static/images/docs/feature-toolbar-button-hhvm-toolbar.png and /dev/null differ diff --git a/docs/static/images/docs/feature-toolbar-button-nuclide-health.png b/docs/static/images/docs/feature-toolbar-button-nuclide-health.png deleted file mode 100644 index 85ea2e5819..0000000000 Binary files a/docs/static/images/docs/feature-toolbar-button-nuclide-health.png and /dev/null differ diff --git a/docs/static/images/docs/feature-toolbar-button-nuclide-settings.png b/docs/static/images/docs/feature-toolbar-button-nuclide-settings.png deleted file mode 100644 index c64f9dac36..0000000000 Binary files a/docs/static/images/docs/feature-toolbar-button-nuclide-settings.png and /dev/null differ diff --git a/docs/static/images/docs/feature-toolbar-button-outline-view.png b/docs/static/images/docs/feature-toolbar-button-outline-view.png deleted file mode 100644 index 10faa8c320..0000000000 Binary files a/docs/static/images/docs/feature-toolbar-button-outline-view.png and /dev/null differ diff --git a/docs/static/images/docs/feature-toolbar-button-settings-view.png b/docs/static/images/docs/feature-toolbar-button-settings-view.png deleted file mode 100644 index 1f3ccada37..0000000000 Binary files a/docs/static/images/docs/feature-toolbar-button-settings-view.png and /dev/null differ diff --git a/docs/static/images/docs/feature-toolbar-button-task-runner.png b/docs/static/images/docs/feature-toolbar-button-task-runner.png deleted file mode 100644 index 2e4d95200b..0000000000 Binary files a/docs/static/images/docs/feature-toolbar-button-task-runner.png and /dev/null differ diff --git a/docs/static/images/docs/feature-toolbar-button-test-runner.png b/docs/static/images/docs/feature-toolbar-button-test-runner.png deleted file mode 100644 index d52b9a86d2..0000000000 Binary files a/docs/static/images/docs/feature-toolbar-button-test-runner.png and /dev/null differ diff --git a/docs/static/images/docs/feature-toolbar-find-package.png b/docs/static/images/docs/feature-toolbar-find-package.png deleted file mode 100644 index 0ce0623173..0000000000 Binary files a/docs/static/images/docs/feature-toolbar-find-package.png and /dev/null differ diff --git a/docs/static/images/docs/feature-working-set-add.png b/docs/static/images/docs/feature-working-set-add.png deleted file mode 100644 index 82d04502ec..0000000000 Binary files a/docs/static/images/docs/feature-working-set-add.png and /dev/null differ diff --git a/docs/static/images/docs/feature-working-set-all-working-sets.png b/docs/static/images/docs/feature-working-set-all-working-sets.png deleted file mode 100644 index 0af43b0ff0..0000000000 Binary files a/docs/static/images/docs/feature-working-set-all-working-sets.png and /dev/null differ diff --git a/docs/static/images/docs/feature-working-set-begin.png b/docs/static/images/docs/feature-working-set-begin.png deleted file mode 100644 index 38152ef773..0000000000 Binary files a/docs/static/images/docs/feature-working-set-begin.png and /dev/null differ diff --git a/docs/static/images/docs/feature-working-set-created.png b/docs/static/images/docs/feature-working-set-created.png deleted file mode 100644 index 1719eb5ea1..0000000000 Binary files a/docs/static/images/docs/feature-working-set-created.png and /dev/null differ diff --git a/docs/static/images/docs/feature-working-set-deactivate.png b/docs/static/images/docs/feature-working-set-deactivate.png deleted file mode 100644 index a91cce7e23..0000000000 Binary files a/docs/static/images/docs/feature-working-set-deactivate.png and /dev/null differ diff --git a/docs/static/images/docs/feature-working-set-edit.png b/docs/static/images/docs/feature-working-set-edit.png deleted file mode 100644 index 1c55661aed..0000000000 Binary files a/docs/static/images/docs/feature-working-set-edit.png and /dev/null differ diff --git a/docs/static/images/docs/feature-working-set-not-working-set-file.png b/docs/static/images/docs/feature-working-set-not-working-set-file.png deleted file mode 100644 index b581c25490..0000000000 Binary files a/docs/static/images/docs/feature-working-set-not-working-set-file.png and /dev/null differ diff --git a/docs/static/images/docs/feature-working-set-select-active.png b/docs/static/images/docs/feature-working-set-select-active.png deleted file mode 100644 index c0c1256d4f..0000000000 Binary files a/docs/static/images/docs/feature-working-set-select-active.png and /dev/null differ diff --git a/docs/static/images/docs/help-faqs-bookshelf.png b/docs/static/images/docs/help-faqs-bookshelf.png deleted file mode 100644 index a1de969168..0000000000 Binary files a/docs/static/images/docs/help-faqs-bookshelf.png and /dev/null differ diff --git a/docs/static/images/docs/help-faqs-reveal-file-on-switch.png b/docs/static/images/docs/help-faqs-reveal-file-on-switch.png deleted file mode 100644 index 6ef6d1a615..0000000000 Binary files a/docs/static/images/docs/help-faqs-reveal-file-on-switch.png and /dev/null differ diff --git a/docs/static/images/docs/help-troubleshooting-diagnostic-flags.png b/docs/static/images/docs/help-troubleshooting-diagnostic-flags.png deleted file mode 100644 index 0aa27f1e4c..0000000000 Binary files a/docs/static/images/docs/help-troubleshooting-diagnostic-flags.png and /dev/null differ diff --git a/docs/static/images/docs/language-cpp-autocomplete.png b/docs/static/images/docs/language-cpp-autocomplete.png deleted file mode 100644 index ca9950b4a5..0000000000 Binary files a/docs/static/images/docs/language-cpp-autocomplete.png and /dev/null differ diff --git a/docs/static/images/docs/language-cpp-code-diagnostics-gutter-fix.png b/docs/static/images/docs/language-cpp-code-diagnostics-gutter-fix.png deleted file mode 100644 index af50a4cbcc..0000000000 Binary files a/docs/static/images/docs/language-cpp-code-diagnostics-gutter-fix.png and /dev/null differ diff --git a/docs/static/images/docs/language-cpp-code-diagnostics.png b/docs/static/images/docs/language-cpp-code-diagnostics.png deleted file mode 100644 index c4f81c0c2b..0000000000 Binary files a/docs/static/images/docs/language-cpp-code-diagnostics.png and /dev/null differ diff --git a/docs/static/images/docs/language-cpp-code-formatting-after.png b/docs/static/images/docs/language-cpp-code-formatting-after.png deleted file mode 100644 index d9bc89e575..0000000000 Binary files a/docs/static/images/docs/language-cpp-code-formatting-after.png and /dev/null differ diff --git a/docs/static/images/docs/language-cpp-code-formatting-before.png b/docs/static/images/docs/language-cpp-code-formatting-before.png deleted file mode 100644 index d24e716af3..0000000000 Binary files a/docs/static/images/docs/language-cpp-code-formatting-before.png and /dev/null differ diff --git a/docs/static/images/docs/language-cpp-jump-to-declaration-link.png b/docs/static/images/docs/language-cpp-jump-to-declaration-link.png deleted file mode 100644 index 83436731c0..0000000000 Binary files a/docs/static/images/docs/language-cpp-jump-to-declaration-link.png and /dev/null differ diff --git a/docs/static/images/docs/language-cpp-jump-to-declaration-result.png b/docs/static/images/docs/language-cpp-jump-to-declaration-result.png deleted file mode 100644 index 27cf36651f..0000000000 Binary files a/docs/static/images/docs/language-cpp-jump-to-declaration-result.png and /dev/null differ diff --git a/docs/static/images/docs/language-cpp-type-hint-pinned.png b/docs/static/images/docs/language-cpp-type-hint-pinned.png deleted file mode 100644 index ec6310dca6..0000000000 Binary files a/docs/static/images/docs/language-cpp-type-hint-pinned.png and /dev/null differ diff --git a/docs/static/images/docs/language-cpp-type-hint.png b/docs/static/images/docs/language-cpp-type-hint.png deleted file mode 100644 index d101490c5d..0000000000 Binary files a/docs/static/images/docs/language-cpp-type-hint.png and /dev/null differ diff --git a/docs/static/images/docs/language-flow-autocomplete.png b/docs/static/images/docs/language-flow-autocomplete.png deleted file mode 100644 index ac643177b1..0000000000 Binary files a/docs/static/images/docs/language-flow-autocomplete.png and /dev/null differ diff --git a/docs/static/images/docs/language-flow-code-diagnostics-gutter.png b/docs/static/images/docs/language-flow-code-diagnostics-gutter.png deleted file mode 100644 index 695dd6ac5c..0000000000 Binary files a/docs/static/images/docs/language-flow-code-diagnostics-gutter.png and /dev/null differ diff --git a/docs/static/images/docs/language-flow-code-diagnostics.png b/docs/static/images/docs/language-flow-code-diagnostics.png deleted file mode 100644 index 9b4456ef4e..0000000000 Binary files a/docs/static/images/docs/language-flow-code-diagnostics.png and /dev/null differ diff --git a/docs/static/images/docs/language-flow-jump-to-definition-link.png b/docs/static/images/docs/language-flow-jump-to-definition-link.png deleted file mode 100644 index b2bd77532d..0000000000 Binary files a/docs/static/images/docs/language-flow-jump-to-definition-link.png and /dev/null differ diff --git a/docs/static/images/docs/language-flow-jump-to-definition-result.png b/docs/static/images/docs/language-flow-jump-to-definition-result.png deleted file mode 100644 index 7d1858173e..0000000000 Binary files a/docs/static/images/docs/language-flow-jump-to-definition-result.png and /dev/null differ diff --git a/docs/static/images/docs/language-flow-pinned-typehint.png b/docs/static/images/docs/language-flow-pinned-typehint.png deleted file mode 100644 index 2b67519c46..0000000000 Binary files a/docs/static/images/docs/language-flow-pinned-typehint.png and /dev/null differ diff --git a/docs/static/images/docs/language-flow-type-coverage-inline.png b/docs/static/images/docs/language-flow-type-coverage-inline.png deleted file mode 100644 index cdb4dd3ab4..0000000000 Binary files a/docs/static/images/docs/language-flow-type-coverage-inline.png and /dev/null differ diff --git a/docs/static/images/docs/language-flow-type-coverage.png b/docs/static/images/docs/language-flow-type-coverage.png deleted file mode 100644 index 37585732fa..0000000000 Binary files a/docs/static/images/docs/language-flow-type-coverage.png and /dev/null differ diff --git a/docs/static/images/docs/language-flow-typehint.png b/docs/static/images/docs/language-flow-typehint.png deleted file mode 100644 index 82cc91d778..0000000000 Binary files a/docs/static/images/docs/language-flow-typehint.png and /dev/null differ diff --git a/docs/static/images/docs/language-hack-autocomplete.png b/docs/static/images/docs/language-hack-autocomplete.png deleted file mode 100644 index 1c8341b3aa..0000000000 Binary files a/docs/static/images/docs/language-hack-autocomplete.png and /dev/null differ diff --git a/docs/static/images/docs/language-hack-badly-formatted.png b/docs/static/images/docs/language-hack-badly-formatted.png deleted file mode 100644 index c7d3f9229d..0000000000 Binary files a/docs/static/images/docs/language-hack-badly-formatted.png and /dev/null differ diff --git a/docs/static/images/docs/language-hack-code-diagnostics-gutter.png b/docs/static/images/docs/language-hack-code-diagnostics-gutter.png deleted file mode 100644 index f1af2d1970..0000000000 Binary files a/docs/static/images/docs/language-hack-code-diagnostics-gutter.png and /dev/null differ diff --git a/docs/static/images/docs/language-hack-code-diagnostics.png b/docs/static/images/docs/language-hack-code-diagnostics.png deleted file mode 100644 index 7042893b14..0000000000 Binary files a/docs/static/images/docs/language-hack-code-diagnostics.png and /dev/null differ diff --git a/docs/static/images/docs/language-hack-jump-to-definition-link.png b/docs/static/images/docs/language-hack-jump-to-definition-link.png deleted file mode 100644 index 7b6f9a3440..0000000000 Binary files a/docs/static/images/docs/language-hack-jump-to-definition-link.png and /dev/null differ diff --git a/docs/static/images/docs/language-hack-jump-to-definition-result.png b/docs/static/images/docs/language-hack-jump-to-definition-result.png deleted file mode 100644 index be64f9c25c..0000000000 Binary files a/docs/static/images/docs/language-hack-jump-to-definition-result.png and /dev/null differ diff --git a/docs/static/images/docs/language-hack-pinned-typehint.png b/docs/static/images/docs/language-hack-pinned-typehint.png deleted file mode 100644 index 17161f9784..0000000000 Binary files a/docs/static/images/docs/language-hack-pinned-typehint.png and /dev/null differ diff --git a/docs/static/images/docs/language-hack-type-coverage-inline.png b/docs/static/images/docs/language-hack-type-coverage-inline.png deleted file mode 100644 index dab2585e72..0000000000 Binary files a/docs/static/images/docs/language-hack-type-coverage-inline.png and /dev/null differ diff --git a/docs/static/images/docs/language-hack-type-coverage.png b/docs/static/images/docs/language-hack-type-coverage.png deleted file mode 100644 index c664e62874..0000000000 Binary files a/docs/static/images/docs/language-hack-type-coverage.png and /dev/null differ diff --git a/docs/static/images/docs/language-hack-typehint.png b/docs/static/images/docs/language-hack-typehint.png deleted file mode 100644 index 0184cd8c3e..0000000000 Binary files a/docs/static/images/docs/language-hack-typehint.png and /dev/null differ diff --git a/docs/static/images/docs/language-hack-well-formatted.png b/docs/static/images/docs/language-hack-well-formatted.png deleted file mode 100644 index e6360af631..0000000000 Binary files a/docs/static/images/docs/language-hack-well-formatted.png and /dev/null differ diff --git a/docs/static/images/docs/language-objc-after-bracket-insert.png b/docs/static/images/docs/language-objc-after-bracket-insert.png deleted file mode 100644 index af847c75e7..0000000000 Binary files a/docs/static/images/docs/language-objc-after-bracket-insert.png and /dev/null differ diff --git a/docs/static/images/docs/language-objc-after-colon-indent.png b/docs/static/images/docs/language-objc-after-colon-indent.png deleted file mode 100644 index f8a23978df..0000000000 Binary files a/docs/static/images/docs/language-objc-after-colon-indent.png and /dev/null differ diff --git a/docs/static/images/docs/language-objc-auto-bracket-completion-setting.png b/docs/static/images/docs/language-objc-auto-bracket-completion-setting.png deleted file mode 100644 index 73e1be7311..0000000000 Binary files a/docs/static/images/docs/language-objc-auto-bracket-completion-setting.png and /dev/null differ diff --git a/docs/static/images/docs/language-objc-autocomplete.png b/docs/static/images/docs/language-objc-autocomplete.png deleted file mode 100644 index 7b4dbe2b1f..0000000000 Binary files a/docs/static/images/docs/language-objc-autocomplete.png and /dev/null differ diff --git a/docs/static/images/docs/language-objc-before-bracket-insert.png b/docs/static/images/docs/language-objc-before-bracket-insert.png deleted file mode 100644 index 53665b786e..0000000000 Binary files a/docs/static/images/docs/language-objc-before-bracket-insert.png and /dev/null differ diff --git a/docs/static/images/docs/language-objc-before-colon-indent.png b/docs/static/images/docs/language-objc-before-colon-indent.png deleted file mode 100644 index 8826969217..0000000000 Binary files a/docs/static/images/docs/language-objc-before-colon-indent.png and /dev/null differ diff --git a/docs/static/images/docs/language-objc-code-diagnostics.png b/docs/static/images/docs/language-objc-code-diagnostics.png deleted file mode 100644 index cf44c30670..0000000000 Binary files a/docs/static/images/docs/language-objc-code-diagnostics.png and /dev/null differ diff --git a/docs/static/images/docs/language-objc-jump-to-definition-link.png b/docs/static/images/docs/language-objc-jump-to-definition-link.png deleted file mode 100644 index b846a213ca..0000000000 Binary files a/docs/static/images/docs/language-objc-jump-to-definition-link.png and /dev/null differ diff --git a/docs/static/images/docs/language-objc-jump-to-definition-result.png b/docs/static/images/docs/language-objc-jump-to-definition-result.png deleted file mode 100644 index 3d7d1d04e6..0000000000 Binary files a/docs/static/images/docs/language-objc-jump-to-definition-result.png and /dev/null differ diff --git a/docs/static/images/docs/language-objc-lint-gutter.png b/docs/static/images/docs/language-objc-lint-gutter.png deleted file mode 100644 index c3f8a06fb9..0000000000 Binary files a/docs/static/images/docs/language-objc-lint-gutter.png and /dev/null differ diff --git a/docs/static/images/docs/language-objc-pinned-typehint.png b/docs/static/images/docs/language-objc-pinned-typehint.png deleted file mode 100644 index 45f16c7492..0000000000 Binary files a/docs/static/images/docs/language-objc-pinned-typehint.png and /dev/null differ diff --git a/docs/static/images/docs/language-objc-typehint.png b/docs/static/images/docs/language-objc-typehint.png deleted file mode 100644 index 3c6e349fe4..0000000000 Binary files a/docs/static/images/docs/language-objc-typehint.png and /dev/null differ diff --git a/docs/static/images/docs/language-python-autocomplete.png b/docs/static/images/docs/language-python-autocomplete.png deleted file mode 100644 index 3964af52bb..0000000000 Binary files a/docs/static/images/docs/language-python-autocomplete.png and /dev/null differ diff --git a/docs/static/images/docs/language-python-code-diagnostics.png b/docs/static/images/docs/language-python-code-diagnostics.png deleted file mode 100644 index 6258a11cb5..0000000000 Binary files a/docs/static/images/docs/language-python-code-diagnostics.png and /dev/null differ diff --git a/docs/static/images/docs/language-python-code-format-after.png b/docs/static/images/docs/language-python-code-format-after.png deleted file mode 100644 index c72bf88e1f..0000000000 Binary files a/docs/static/images/docs/language-python-code-format-after.png and /dev/null differ diff --git a/docs/static/images/docs/language-python-code-format-before.png b/docs/static/images/docs/language-python-code-format-before.png deleted file mode 100644 index 3655f81b1b..0000000000 Binary files a/docs/static/images/docs/language-python-code-format-before.png and /dev/null differ diff --git a/docs/static/images/docs/language-python-jump-to-definition-link.png b/docs/static/images/docs/language-python-jump-to-definition-link.png deleted file mode 100644 index f05c4b4ad1..0000000000 Binary files a/docs/static/images/docs/language-python-jump-to-definition-link.png and /dev/null differ diff --git a/docs/static/images/docs/language-python-jump-to-definition-result.png b/docs/static/images/docs/language-python-jump-to-definition-result.png deleted file mode 100644 index ab265880fe..0000000000 Binary files a/docs/static/images/docs/language-python-jump-to-definition-result.png and /dev/null differ diff --git a/docs/static/images/docs/language-python-outline-view.png b/docs/static/images/docs/language-python-outline-view.png deleted file mode 100644 index 1e9f64bd49..0000000000 Binary files a/docs/static/images/docs/language-python-outline-view.png and /dev/null differ diff --git a/docs/static/images/docs/language-swift-autocompletion.png b/docs/static/images/docs/language-swift-autocompletion.png deleted file mode 100644 index a5a6d5b21c..0000000000 Binary files a/docs/static/images/docs/language-swift-autocompletion.png and /dev/null differ diff --git a/docs/static/images/docs/language-swift-toolchain-path-setting.png b/docs/static/images/docs/language-swift-toolchain-path-setting.png deleted file mode 100644 index 498f468518..0000000000 Binary files a/docs/static/images/docs/language-swift-toolchain-path-setting.png and /dev/null differ diff --git a/docs/static/images/docs/platform-android-simulator-output.png b/docs/static/images/docs/platform-android-simulator-output.png deleted file mode 100644 index 0cae1613dc..0000000000 Binary files a/docs/static/images/docs/platform-android-simulator-output.png and /dev/null differ diff --git a/docs/static/images/docs/platform-android-toggle-simulator.png b/docs/static/images/docs/platform-android-toggle-simulator.png deleted file mode 100644 index efc6ae71a1..0000000000 Binary files a/docs/static/images/docs/platform-android-toggle-simulator.png and /dev/null differ diff --git a/docs/static/images/docs/platform-ios-buck-build.png b/docs/static/images/docs/platform-ios-buck-build.png deleted file mode 100644 index 2c7742ecd0..0000000000 Binary files a/docs/static/images/docs/platform-ios-buck-build.png and /dev/null differ diff --git a/docs/static/images/docs/platform-ios-native-autocomplete.png b/docs/static/images/docs/platform-ios-native-autocomplete.png deleted file mode 100644 index a4ae52d973..0000000000 Binary files a/docs/static/images/docs/platform-ios-native-autocomplete.png and /dev/null differ diff --git a/docs/static/images/docs/platform-ios-simulator-output.png b/docs/static/images/docs/platform-ios-simulator-output.png deleted file mode 100644 index a37a26f3c9..0000000000 Binary files a/docs/static/images/docs/platform-ios-simulator-output.png and /dev/null differ diff --git a/docs/static/images/docs/platform-ios-toggle-simulator.png b/docs/static/images/docs/platform-ios-toggle-simulator.png deleted file mode 100644 index 254d19b2b3..0000000000 Binary files a/docs/static/images/docs/platform-ios-toggle-simulator.png and /dev/null differ diff --git a/docs/static/images/docs/platform-react-native-debug-options.png b/docs/static/images/docs/platform-react-native-debug-options.png deleted file mode 100644 index 36ae503430..0000000000 Binary files a/docs/static/images/docs/platform-react-native-debug-options.png and /dev/null differ diff --git a/docs/static/images/docs/platform-react-native-debugger-waititng.png b/docs/static/images/docs/platform-react-native-debugger-waititng.png deleted file mode 100644 index 513f0c0fe8..0000000000 Binary files a/docs/static/images/docs/platform-react-native-debugger-waititng.png and /dev/null differ diff --git a/docs/static/images/docs/platform-react-native-debugging-command-palette.png b/docs/static/images/docs/platform-react-native-debugging-command-palette.png deleted file mode 100644 index 922b36f077..0000000000 Binary files a/docs/static/images/docs/platform-react-native-debugging-command-palette.png and /dev/null differ diff --git a/docs/static/images/docs/platform-react-native-debugging.png b/docs/static/images/docs/platform-react-native-debugging.png deleted file mode 100644 index ee65d6e744..0000000000 Binary files a/docs/static/images/docs/platform-react-native-debugging.png and /dev/null differ diff --git a/docs/static/images/docs/platform-react-native-element-inspector.png b/docs/static/images/docs/platform-react-native-element-inspector.png deleted file mode 100644 index 89b3db5652..0000000000 Binary files a/docs/static/images/docs/platform-react-native-element-inspector.png and /dev/null differ diff --git a/docs/static/images/docs/platform-react-native-feature-autocomplete.png b/docs/static/images/docs/platform-react-native-feature-autocomplete.png deleted file mode 100644 index 2db25bb7ff..0000000000 Binary files a/docs/static/images/docs/platform-react-native-feature-autocomplete.png and /dev/null differ diff --git a/docs/static/images/docs/platform-react-native-show-inspector.png b/docs/static/images/docs/platform-react-native-show-inspector.png deleted file mode 100644 index 25801a05c6..0000000000 Binary files a/docs/static/images/docs/platform-react-native-show-inspector.png and /dev/null differ diff --git a/docs/static/images/docs/platform-react-native-start-packager.png b/docs/static/images/docs/platform-react-native-start-packager.png deleted file mode 100644 index 09d9ee5058..0000000000 Binary files a/docs/static/images/docs/platform-react-native-start-packager.png and /dev/null differ diff --git a/docs/static/images/docs/promo-debugger.png b/docs/static/images/docs/promo-debugger.png deleted file mode 100644 index b071518e1d..0000000000 Binary files a/docs/static/images/docs/promo-debugger.png and /dev/null differ diff --git a/docs/static/images/docs/promo-flow.png b/docs/static/images/docs/promo-flow.png deleted file mode 100644 index edf4035a8a..0000000000 Binary files a/docs/static/images/docs/promo-flow.png and /dev/null differ diff --git a/docs/static/images/docs/promo-hack.png b/docs/static/images/docs/promo-hack.png deleted file mode 100644 index 3eb4d3cf5f..0000000000 Binary files a/docs/static/images/docs/promo-hack.png and /dev/null differ diff --git a/docs/static/images/docs/promo-mercurial.png b/docs/static/images/docs/promo-mercurial.png deleted file mode 100644 index 1bef66ebd8..0000000000 Binary files a/docs/static/images/docs/promo-mercurial.png and /dev/null differ diff --git a/docs/static/images/docs/promo-remote-development.png b/docs/static/images/docs/promo-remote-development.png deleted file mode 100644 index a1004843e9..0000000000 Binary files a/docs/static/images/docs/promo-remote-development.png and /dev/null differ diff --git a/docs/static/images/docs/promo-task-runner.png b/docs/static/images/docs/promo-task-runner.png deleted file mode 100644 index 179dd9868e..0000000000 Binary files a/docs/static/images/docs/promo-task-runner.png and /dev/null differ diff --git a/docs/static/images/docs/promo-working-sets.png b/docs/static/images/docs/promo-working-sets.png deleted file mode 100644 index e4b92fed15..0000000000 Binary files a/docs/static/images/docs/promo-working-sets.png and /dev/null differ diff --git a/docs/static/images/docs/quick-start-getting-started-add-project.png b/docs/static/images/docs/quick-start-getting-started-add-project.png deleted file mode 100644 index 73a43ed6f2..0000000000 Binary files a/docs/static/images/docs/quick-start-getting-started-add-project.png and /dev/null differ diff --git a/docs/static/images/docs/quick-start-getting-started-diff-view.png b/docs/static/images/docs/quick-start-getting-started-diff-view.png deleted file mode 100644 index f66592c658..0000000000 Binary files a/docs/static/images/docs/quick-start-getting-started-diff-view.png and /dev/null differ diff --git a/docs/static/images/docs/quick-start-getting-started-file-tree-view.png b/docs/static/images/docs/quick-start-getting-started-file-tree-view.png deleted file mode 100644 index 350a97774d..0000000000 Binary files a/docs/static/images/docs/quick-start-getting-started-file-tree-view.png and /dev/null differ diff --git a/docs/static/images/docs/quick-start-getting-started-home.png b/docs/static/images/docs/quick-start-getting-started-home.png deleted file mode 100644 index e81c05ee4d..0000000000 Binary files a/docs/static/images/docs/quick-start-getting-started-home.png and /dev/null differ diff --git a/docs/static/images/docs/quick-start-getting-started-quick-launch-menu.png b/docs/static/images/docs/quick-start-getting-started-quick-launch-menu.png deleted file mode 100644 index f3d59ef911..0000000000 Binary files a/docs/static/images/docs/quick-start-getting-started-quick-launch-menu.png and /dev/null differ diff --git a/docs/static/images/docs/quick-start-getting-started-quick-open.png b/docs/static/images/docs/quick-start-getting-started-quick-open.png deleted file mode 100644 index da11b2650f..0000000000 Binary files a/docs/static/images/docs/quick-start-getting-started-quick-open.png and /dev/null differ diff --git a/docs/static/images/docs/quick-start-getting-started-remote-connection-dialog.png b/docs/static/images/docs/quick-start-getting-started-remote-connection-dialog.png deleted file mode 100644 index acc22a73a4..0000000000 Binary files a/docs/static/images/docs/quick-start-getting-started-remote-connection-dialog.png and /dev/null differ diff --git a/docs/static/images/help/troubleshooting-flow-executable-setting.png b/docs/static/images/help/troubleshooting-flow-executable-setting.png deleted file mode 100644 index 5eee008387..0000000000 Binary files a/docs/static/images/help/troubleshooting-flow-executable-setting.png and /dev/null differ diff --git a/docs/static/images/help/troubleshooting-module-not-found.png b/docs/static/images/help/troubleshooting-module-not-found.png deleted file mode 100644 index 43fd988ff9..0000000000 Binary files a/docs/static/images/help/troubleshooting-module-not-found.png and /dev/null differ diff --git a/docs/static/logo.png b/docs/static/logo.png deleted file mode 100644 index bc43aaf81c..0000000000 Binary files a/docs/static/logo.png and /dev/null differ diff --git a/docs/static/logo_nav.png b/docs/static/logo_nav.png deleted file mode 100644 index 0ac0eed7cb..0000000000 Binary files a/docs/static/logo_nav.png and /dev/null differ diff --git a/docs/static/og_image.png b/docs/static/og_image.png deleted file mode 100644 index 79c013f322..0000000000 Binary files a/docs/static/og_image.png and /dev/null differ diff --git a/docs/static/oss_logo.png b/docs/static/oss_logo.png deleted file mode 100644 index 8183e289b1..0000000000 Binary files a/docs/static/oss_logo.png and /dev/null differ diff --git a/docs/static/search.png b/docs/static/search.png deleted file mode 100644 index 222fb660da..0000000000 Binary files a/docs/static/search.png and /dev/null differ diff --git a/flow-libs/atom-jasmine.js.flow b/flow-libs/atom-jasmine.js.flow deleted file mode 100644 index b4cd47bae6..0000000000 --- a/flow-libs/atom-jasmine.js.flow +++ /dev/null @@ -1,23 +0,0 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the license found in the LICENSE file in - * the root directory of this source tree. - * - * @flow - */ - -// Type declarations for Atom's extensions to Jasmine v1.3 -// https://github.com/atom/atom/blob/master/spec/spec-helper.coffee - -/** Note that waitsForPromise has an optional first argument. */ -declare function waitsForPromise( - optionsOrFunc: {timeout?: number, shouldReject?: boolean, label?: string} | () => Promise, - func?: () => Promise -): void; - -/** - * deltaInMilliseconds defaults to 1. - */ -declare function advanceClock(deltaInMilliseconds?: number): void; diff --git a/flow-libs/atom.js.flow b/flow-libs/atom.js.flow deleted file mode 100644 index cb80ebc58d..0000000000 --- a/flow-libs/atom.js.flow +++ /dev/null @@ -1,1762 +0,0 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the license found in the LICENSE file in - * the root directory of this source tree. - * - * @flow - */ - -/** - * Private Classes - */ - -// Octicons v4.4.0. List extracted from the atom-styleguide package. -type atom$Octicon = 'alert' | 'alignment-align' | 'alignment-aligned-to' | 'alignment-unalign' | - 'arrow-down' | 'arrow-left' | 'arrow-right' | 'arrow-small-down' | 'arrow-small-left' | - 'arrow-small-right' | 'arrow-small-up' | 'arrow-up' | 'beaker' | 'beer' | 'bell' | 'bold' | - 'book' | 'bookmark' | 'briefcase' | 'broadcast' | 'browser' | 'bug' | 'calendar' | 'check' | - 'checklist' | 'chevron-down' | 'chevron-left' | 'chevron-right' | 'chevron-up' | 'circle-slash' | - 'circuit-board' | 'clippy' | 'clock' | 'cloud-download' | 'cloud-upload' | 'code' | 'color-mode' | - 'comment' | 'comment-add' | 'comment-discussion' | 'credit-card' | 'dash' | 'dashboard' | - 'database' | 'desktop-download' | 'device-camera' | 'device-camera-video' | 'device-desktop' | - 'device-mobile' | 'diff' | 'diff-added' | 'diff-ignored' | 'diff-modified' | 'diff-removed' | - 'diff-renamed' | 'ellipses' | 'ellipsis' | 'eye' | 'eye-unwatch' | 'eye-watch' | 'file' | - 'file-add' | 'file-binary' | 'file-code' | 'file-directory' | 'file-directory-create' | - 'file-media' | 'file-pdf' | 'file-submodule' | 'file-symlink-directory' | 'file-symlink-file' | - 'file-text' | 'file-zip' | 'flame' | 'fold' | 'gear' | 'gift' | 'gist' | 'gist-fork' | - 'gist-new' | 'gist-private' | 'gist-secret' | 'git-branch' | 'git-branch-create' | - 'git-branch-delete' | 'git-commit' | 'git-compare' | 'git-fork-private' | 'git-merge' | - 'git-pull-request' | 'git-pull-request-abandoned' | 'globe' | 'grabber' | 'graph' | 'heart' | - 'history' | 'home' | 'horizontal-rule' | 'hourglass' | 'hubot' | 'inbox' | 'info' | - 'issue-closed' | 'issue-opened' | 'issue-reopened' | 'italic' | 'jersey' | 'jump-down' | - 'jump-left' | 'jump-right' | 'jump-up' | 'key' | 'keyboard' | 'law' | 'light-bulb' | 'link' | - 'link-external' | 'list-ordered' | 'list-unordered' | 'location' | 'lock' | 'log-in' | 'log-out' | - 'logo-gist' | 'logo-github' | 'mail' | 'mail-read' | 'mail-reply' | 'mark-github' | 'markdown' | - 'megaphone' | 'mention' | 'microscope' | 'milestone' | 'mirror' | 'mirror-private' | - 'mirror-public' | 'mortar-board' | 'move-down' | 'move-left' | 'move-right' | 'move-up' | 'mute' | - 'no-newline' | 'octoface' | 'organization' | 'package' | 'paintcan' | 'pencil' | 'person' | - 'person-add' | 'person-follow' | 'pin' | 'playback-fast-forward' | 'playback-pause' | - 'playback-play' | 'playback-rewind' | 'plug' | 'plus-small' | 'plus' | 'podium' | - 'primitive-dot' | 'primitive-square' | 'pulse' | 'puzzle' | 'question' | 'quote' | 'radio-tower' | - 'remove-close' | 'reply' | 'repo' | 'repo-clone' | 'repo-create' | 'repo-delete' | - 'repo-force-push' | 'repo-forked' | 'repo-pull' | 'repo-push' | 'repo-sync' | 'rocket' | 'rss' | - 'ruby' | 'screen-full' | 'screen-normal' | 'search' | 'search-save' | 'server' | 'settings' | - 'shield' | 'sign-in' | 'sign-out' | 'smiley' | 'split' | 'squirrel' | 'star' | 'star-add' | - 'star-delete' | 'steps' | 'stop' | 'sync' | 'tag' | 'tag-add' | 'tag-remove' | 'tasklist' | - 'telescope' | 'terminal' | 'text-size' | 'three-bars' | 'thumbsdown' | 'thumbsup' | 'tools' | - 'trashcan' | 'triangle-down' | 'triangle-left' | 'triangle-right' | 'triangle-up' | 'unfold' | - 'unmute' | 'unverified' | 'verified' | 'versions' | 'watch' | 'x' | 'zap'; - -declare class atom$Model { - destroy(): void, - isDestroyed(): boolean, -} - -declare class atom$Package { - path: string, - activateTime: number, - mainModule: any, - metadata: Object, - name: string, - loadTime: number, - getType(): 'atom' | 'textmate' | 'theme', - hasActivationCommands(): boolean, - hasActivationHooks(): boolean, - getActivationHooks(): Array, - onDidDeactivate(cb: () => mixed): IDisposable, - activateNow(): void, - // Undocumented - getCanDeferMainModuleRequireStorageKey(): string, -} - -/** - * Essential Classes - */ - -type atom$CommandCallback = (event: Event) => mixed; - -declare class atom$CommandRegistry { - // Methods - add( - target: string | HTMLElement, - commandNameOrCommands: string | {[commandName: string]: atom$CommandCallback}, - callback?: atom$CommandCallback - ): IDisposable, - dispatch(target: HTMLElement, commandName: string): void, - onDidDispatch(callback: (event: Event) => mixed): IDisposable, - onWillDispatch(callback: (event: Event) => mixed): IDisposable, -} - -declare class atom$CompositeDisposable { - constructor(...disposables: IDisposable[]): void, - dispose(): void, - - add(disposable: IDisposable): void, - remove(disposable: IDisposable): void, - clear(): void, -} - -type atom$ConfigType = - 'boolean' | 'string' | 'integer' | 'number' | - 'array' | 'object' | 'color' | 'any'; - -type atom$ConfigSchema = { - default?: mixed, - description?: string, - enum?: Array, - maximum?: number, - minimum?: number, - properties?: Object, - title?: string, - type: Array | atom$ConfigType, -}; - -declare class atom$Config { - // Config Subscription - observe( - keyPath: string, - optionsOrCallback?: Object | (value: any) => void, - callback?: (value: any) => void - ): IDisposable, - - onDidChange( - keyPathOrCallback: string | (event: Object) => void, - optionsOrCallback?: Object | (event: Object) => void, - callback?: (event: Object) => void - ): IDisposable, - - // Managing Settings - get( - keyPath?: string, - options?: { - excludeSources?: Array, - sources?: Array, - scope?: Object, - } - ): mixed, - - set( - keyPath: string, - value: ?mixed, - options?: { - scopeSelector?: string, - source?: string, - }, - ): boolean, - - unset( - keyPath: string, - options?: { - scopeSelector?: string, - source?: string, - } - ): void, - - getUserConfigPath(): string, - - // Undocumented Methods - getRawValue(keyPath: ?string, options: {excludeSources?: string, sources?: string}): mixed, - getSchema(keyPath: string): atom$ConfigSchema, - save(): void, - setRawValue(keyPath: string, value: mixed): void, - setSchema( - keyPath: string, - schema: atom$ConfigSchema, - ): void, -} - -declare class atom$Cursor { - // Event Subscription - onDidChangePosition( - callback: (event: { - oldBufferPosition: atom$Point, - oldScreenPosition: atom$Point, - newBufferPosition: atom$Point, - newScreenPosition: atom$Point, - textChanged: boolean, - Cursor: atom$Cursor, - }) => mixed, - ): IDisposable, - - // Managing Cursor Position - getBufferRow(): number, - getBufferColumn(): number, - getBufferPosition(): atom$Point, - - // Cursor Position Details - // Moving the Cursor - - // Local Positions and Ranges - getCurrentWordBufferRange(options?: {wordRegex: RegExp}): atom$Range, - getCurrentWordPrefix(): string, - - // Visibility - // Comparing to another cursor - // Utilities - wordRegExp(options?: {includeNonWordCharacters: boolean}): RegExp, -} - -declare class atom$Decoration { - destroy(): void, - onDidChangeProperties( - callback: (event: {oldProperties: Object, newProperties: Object}) => mixed - ): IDisposable, - getMarker(): atom$Marker, - getProperties(): Object, - setProperties(properties: mixed): void, -} - -declare class atom$Disposable { - constructor(disposalAction?: (...args: any[]) => any): void, - dispose(): void, -} - -declare class atom$Emitter { - dispose(): void, - on(name: string, callback: (v: any) => mixed): IDisposable, - preempt(name: string, callback: (v: any) => void): IDisposable, - // This is a flow hack to prevent emitting more than one value. - // `EventEmitter` allows emitting any number of values - making this a land - // mine, since we tend to think of `emit` as interchangeable. - // This hack only works if the extra value is not `undefined`, so this isn't - // full-proof, but it works for most cases. - emit(name: string, value: any, ...no_extra_args_allowed: Array): void, -} - -declare class atom$Gutter { - name: string, - destroy(): void, - decorateMarker( - marker: atom$Marker, - options?: {'class'?: string, item?: Object | HTMLElement}): void, - show(): void, - hide(): void, - onDidDestroy(callback: () => void): IDisposable, -} - -declare class atom$Marker { - destroy(): void, - getBufferRange(): atom$Range, - getStartBufferPosition(): atom$Point, - onDidChange(callback: (event: { - oldHeadScreenPosition: atom$Point, - newHeadScreenPosition: atom$Point, - oldTailScreenPosition: atom$Point, - newTailScreenPosition: atom$Point, - - oldHeadBufferPosition: atom$Point, - newHeadBufferPosition: atom$Point, - oldTailBufferPosition: atom$Point, - newTailBufferPosition: atom$Point, - - isValid: boolean, - textChanged: boolean, - }) => void): IDisposable, - isValid(): boolean, - isDestroyed(): boolean, - onDidDestroy(callback: () => void): IDisposable, - setBufferRange( - range: atom$RangeLike, - properties?: {reversed: boolean}, - ): void, -} - -declare class atom$ServiceHub { - provide(keyPath: string, version: string, service: T): IDisposable, - consume( - keyPath: string, - versionRange: string, - callback: (provider: T) => mixed - ): IDisposable, -} - -type atom$PackageMetadata = { - name: string, - version: string, -}; - -declare class atom$PackageManager { - // Event Subscription - onDidLoadInitialPackages(callback: () => void): IDisposable, - onDidActivateInitialPackages(callback: () => void): IDisposable, - onDidActivatePackage(callback: (pkg: atom$Package) => mixed): IDisposable, - onDidDeactivatePackage(callback: (pkg: atom$Package) => mixed): IDisposable, - onDidLoadPackage(callback: (pkg: atom$Package) => mixed): IDisposable, - onDidTriggerActivationHook(activationHook: string, callback: () => mixed): IDisposable, - - // Package system data - getApmPath(): string, - getPackageDirPaths(): Array, - - // General package data - resolvePackagePath(name: string): ?string, - isBundledPackage(name: string): boolean, - - // Enabling and disabling packages - enablePackage(name: string): ?atom$Package, - disablePackage(name: string): ?atom$Package, - isPackageDisabled(name: string): boolean, - - // Accessing active packages - getActivePackage(name: string): ?atom$Package, - getActivePackages(): Array, - isPackageActive(name: string): boolean, - - // Activating and deactivating packages - activatePackage(name: string): Promise, - - // Accessing loaded packages - getLoadedPackage(name: string): ?atom$Package, - getLoadedPackages(): Array, - isPackageLoaded(name: string): boolean, - - // Accessing available packages - getAvailablePackageNames(): Array, - getAvailablePackageMetadata(): Array, - - // (Undocumented.) - activate(): Promise, - deactivatePackages(): void, - deactivatePackage(name: string): void, - loadPackage(name: string): void, - loadPackages(): void, - serializePackage(pkg: atom$Package): void, - serviceHub: atom$ServiceHub, - packageDirPaths: Array, - triggerActivationHook(hook: string): void, - triggerDeferredActivationHooks(): void, - unloadPackage(name: string): void, - unloadPackages(): void, -} - -declare class atom$StyleManager { - // Event Subscription - - // Reading Style Elements - getStyleElements(): Array, - - // Paths - getUserStyleSheetPath(): string, -} - -type atom$PaneSplitParams = { - copyActiveItem?: boolean, - items?: Array, -}; - -type atom$PaneSplitOrientation = 'horizontal' | 'vertical'; -type atom$PaneSplitSide = 'before' | 'after'; - -// Undocumented class -declare class atom$applicationDelegate { - focusWindow(): Promise, -} - -type atom$PaneParams = { - activeItem?: Object, - applicationDelegate: atom$applicationDelegate, - focused?: boolean, - container: Object, - config: atom$Config, - notificationManager: atom$NotificationManager, - deserializerManager: atom$DeserializerManager, - items?: Array, - itemStackIndices?: Array, - flexScale?: number, -}; - -declare class atom$Pane { - // Items - addItem(item: Object, options?: {index?: number, pending?: boolean}): Object, - getItems(): Array, - getActiveItem(): ?Object, - itemAtIndex(index: number): ?Object, - getActiveItemIndex(): number, - activateItem(item: Object): ?Object, - activateItemAtIndex(index: number): void, - moveItemToPane(item: Object, pane: atom$Pane, index: number): void, - destroyItem(item: Object): boolean, - itemForURI(uri: string): Object, - - // Event subscriptions. - onDidAddItem(cb: (event: {item: Object, index: number}) => void): IDisposable, - onDidRemoveItem(cb: (event: {item: Object, index: number}) => void): IDisposable, - onWillRemoveItem(cb: (event: {item: Object, index: number}) => void): IDisposable, - onDidDestroy(cb: () => void): IDisposable, - observeActiveItem(cb: (item: ?Object) => void): IDisposable, - - // Lifecycle - isActive(): boolean, - activate(): void, - destroy(): void, - - // Splitting - splitLeft(params?: atom$PaneSplitParams): atom$Pane, - splitRight(params?: atom$PaneSplitParams): atom$Pane, - splitUp(params?: atom$PaneSplitParams): atom$Pane, - splitDown(params?: atom$PaneSplitParams): atom$Pane, - split( - orientation: atom$PaneSplitOrientation, - side: atom$PaneSplitSide, - params?: atom$PaneSplitParams, - ): atom$Pane, - - // Undocumented Methods - constructor(params: atom$PaneParams): atom$Pane, - clearPendingItem(): void, - getFlexScale(): number, - getParent(): Object, - removeItem(item: Object, moved: ?boolean): void, - setActiveItem(item: Object): Object, - setFlexScale(flexScale: number): number, -} - -declare type atom$PaneItem = { - // These are all covariant, meaning that these props are read-only. Therefore we can assign an - // object with more strict requirements to an variable of this type. - +getTitle: () => string, - +getLongTitle?: () => string, - +getIconName?: () => string, - +getURI?: () => string, - +onDidChangeIcon?: (cb: (icon: string) => void) => IDisposable, - +onDidChangeTitle?: (cb: (title: string) => void) => IDisposable, - +serialize?: () => Object, -} - -// Undocumented class -declare class atom$PaneAxis { - getFlexScale(): number, - setFlexScale(flexScale: number): number, - getItems(): Array, -} - -// Undocumented class -declare class atom$PaneContainer { - destroy(): void, - getActivePane(): atom$Pane, - getActivePaneItem(): ?Object, - getPanes(): Array, - getPaneItems(): Array, - observePanes(cb: (pane: atom$Pane) => void): IDisposable, - onDidAddPane(cb: (event: {pane: atom$Pane}) => void): IDisposable, - onDidDestroyPane(cb: (event: {pane: atom$Pane}) => void): IDisposable, - onWillDestroyPane(cb: (event: {pane: atom$Pane}) => void): IDisposable, - onDidAddPaneItem(cb: (item: atom$PaneItem) => void): IDisposable, - onDidDestroyPaneItem(cb: (item: atom$Pane) => void): IDisposable, - paneForItem(item: Object): ?atom$Pane, - serialize(): Object, -} - -declare class atom$Panel { - // Construction and Destruction - destroy(): void, - - // Event Subscription - onDidChangeVisible(callback: (visible: boolean) => any): IDisposable, - onDidDestroy(callback: (panel: atom$Panel) => any): IDisposable, - - // Panel Details - getItem(): HTMLElement, - getPriority(): number, - isVisible(): boolean, - hide(): void, - show(): void, -} - -type atom$PointObject = {row: number, column: number}; - -type atom$PointLike = atom$Point -| [number, number] -| atom$PointObject; - -declare class atom$Point { - static fromObject(object: atom$PointLike, copy: ? boolean): atom$Point, - constructor(row: number, column: number): void, - row: number, - column: number, - copy(): atom$Point, - negate(): atom$Point, - - // Comparison - min(point1: atom$Point, point2: atom$Point): atom$Point, - compare(other: atom$Point): -1 | 0 | 1, - isEqual(otherRange: atom$PointLike): boolean, - isLessThan(other: atom$Point): boolean, - isLessThanOrEqual(other: atom$Point): boolean, - isGreaterThan(other: atom$Point): boolean, - isGreaterThanOrEqual(other: atom$Point): boolean, - - // Operations - translate(other: atom$PointLike): atom$Point, - - // Conversion - serialize(): Array, - toArray(): Array, -} - -type atom$RangeObject = { - start: atom$PointObject, - end: atom$PointObject, -}; - -type atom$RangeLike = atom$Range - | atom$RangeObject // TODO: Flow doesn't really handle the real signature below... - | [atom$PointLike, atom$PointLike] - | { - start: atom$PointLike, - end: atom$PointLike, - }; - -declare class atom$Range { - static fromObject( - object: atom$RangeLike, - copy?: boolean, - ): atom$Range, - constructor(pointA: atom$PointLike, pointB: atom$PointLike): void, - compare(other: atom$Range): number, - start: atom$Point, - end: atom$Point, - isEmpty(): boolean, - isEqual(otherRange: atom$RangeLike): boolean, - containsPoint(point: atom$PointLike, exclusive?: boolean): boolean, - containsRange(other: atom$Range, exclusive?: boolean): boolean, - union(other: atom$Range): atom$Range, - serialize(): Array>, -} - -type RawStatusBarTile = { - item: HTMLElement, - priority: number, -}; - -type atom$StatusBarTile = { - getPriority(): number, - getItem(): HTMLElement, - destroy(): void, -}; - -declare class atom$ScopeDescriptor { - constructor(object: {scopes: Array}): void, - getScopesArray(): Array, -} - -/** - * This API is defined at https://github.com/atom/status-bar. - */ -declare class atom$StatusBar { - addLeftTile(tile: RawStatusBarTile): atom$StatusBarTile, - addRightTile(tile: RawStatusBarTile): atom$StatusBarTile, - getLeftTiles(): Array, - getRightTiles(): Array, -} - -// https://github.com/atom/atom/blob/v1.9.0/src/text-editor-registry.coffee -declare class atom$TextEditorRegistry { - add(editor: atom$TextEditor): IDisposable, - remove(editor: atom$TextEditor): boolean, - observe(callback: (editor: atom$TextEditor) => void): IDisposable, - - // Added in 1.11.0 (These are typed optional until older Atoms are dropped) - build?: (params: atom$TextEditorParams) => atom$TextEditor, - - // Private - editors: Set, -} - -declare class atom$ThemeManager { - // Event Subscription - /** - * As recent as Atom 1.0.10, the implementation of this method was: - * - * ``` - * onDidChangeActiveThemes: (callback) -> - * @emitter.on 'did-change-active-themes', callback - * @emitter.on 'did-reload-all', callback # TODO: Remove once deprecated pre-1.0 APIs are gone - * ``` - * - * Due to the nature of CoffeeScript, onDidChangeActiveThemes returns a Disposable even though it - * is not documented as doing so. However, the Disposable that it does return removes the - * subscription on the 'did-reload-all' event (which is supposed to be deprecated) rather than the - * 'did-change-active-themes' one. - */ - onDidChangeActiveThemes(callback: () => mixed): IDisposable, - - // Accessing Loaded Themes - getLoadedThemeNames(): Array, - getLoadedThemes(): Array, // TODO: Define undocumented ThemePackage class. - - // Accessing Active Themes - getActiveThemeNames(): Array, - getActiveThemes(): Array, // TODO: Define undocumented ThemePackage class. - - // Managing Enabled Themes - getEnabledThemeNames(): Array, - - // Private - activateThemes(): Promise, - requireStylesheet(stylesheetPath: string): IDisposable, -} - -type atom$TooltipsPlacementOption = 'top' | 'bottom' | 'left' | 'right' | 'auto'; - -type atom$TooltipsAddOptions = { - title: string, - keyBindingCommand?: string, - keyBindingTarget?: HTMLElement, - animation?: boolean, - container?: string | false, - delay?: number | {show: number, hide: number}, - placement?: atom$TooltipsPlacementOption | () => atom$TooltipsPlacementOption, -}; - -declare class atom$TooltipManager { - add( - target: HTMLElement, - options: atom$TooltipsAddOptions, - ): IDisposable, -} - -type InsertTextOptions = { - select: boolean, - autoIndent: boolean, - autoIndentNewline: boolean, - autoDecreaseIndent: boolean, - normalizeLineEndings: ?boolean, - undo: string, -}; - -type DecorateMarkerParams = { - type: 'line', - class: string, - onlyHead?: boolean, - onlyEmpty?: boolean, - onlyNonEmpty?: boolean, -} | { - type: 'gutter', - class: string, - onlyHead?: boolean, - onlyEmpty?: boolean, - onlyNonEmpty?: boolean, - gutterName?: string, -} | { - type: 'highlight', - class?: string, - gutterName?: string, -} | { - type: 'overlay', - item: Object, - position?: 'head' | 'tail', // Defaults to 'head' when unspecified. -} | { - type: 'block', - item: HTMLElement, - position?: 'before' | 'after', // Defaults to 'before' when unspecified. -}; - -type ChangeCursorPositionEvent = { - oldBufferPosition: atom$Point, - oldScreenPosition: atom$Point, - newBufferPosition: atom$Point, - newScreenPosition: atom$Point, - textChanged: boolean, - cursor: atom$Cursor, -}; - -type MarkerOptions = {| - reversed?: boolean, - tailed?: boolean, - invalidate?: 'never' | 'surround' | 'overlap' | 'inside' | 'touch', - exclusive?: boolean, -|}; - -declare class atom$TextEditor extends atom$Model { - id: number, - firstVisibleScreenRow: number, - rowsPerPage: number, - - // Event Subscription - onDidChange(callback: () => void): IDisposable, - onDidChangePath(callback: () => mixed): IDisposable, - onDidStopChanging(callback: () => void): IDisposable, - onDidChangeCursorPosition(callback: (event: ChangeCursorPositionEvent) => mixed): - IDisposable, - onDidDestroy(callback: () => mixed): IDisposable, - onDidSave(callback: (event: {path: string}) => mixed): IDisposable, - getBuffer(): atom$TextBuffer, - observeGrammar(callback: (grammar: atom$Grammar) => mixed): IDisposable, - onWillInsertText(callback: (event: {cancel: () => void, text: string}) => void): - IDisposable, - // Note that the range property of the event is undocumented. - onDidInsertText(callback: (event: {text: string, range: atom$Range}) => mixed): IDisposable, - onDidChangeSoftWrapped(callback: (softWrapped: boolean) => mixed): IDisposable, - - // File Details - getTitle: () => string, - getLongTitle(): string, - /** - * If you open Atom via Spotlight such that it opens with a tab named - * "untitled" that does not correspond to a file on disk, this will return - * null. - */ - getPath(): ?string, - getURI: () => ?string, - insertNewline(): void, - isModified: () => boolean, - isEmpty(): boolean, - getEncoding(): buffer$Encoding, - setEncoding(encoding: string): void, - getTabLength() : number, - - // File Operations - save(): void, - saveAs(filePath: string): void, - - // Reading Text - getText(): string, - getTextInBufferRange(range: atom$RangeLike): string, - getLineCount(): number, - - // Mutating Text - setText(text: string, options?: InsertTextOptions): void, - setTextInBufferRange( - range: atom$Range, - text: string, - options?: { - normalizeLineEndings?: boolean, - undo?: string, - }, - ): atom$Range, - insertText(text: string): Array | false, - delete: () => void, - backspace: () => void, - duplicateLines: () => void, - - // History - // TextEditor Coordinates - screenPositionForBufferPosition( - bufferPosition: atom$PointLike, - options?: { - wrapBeyondNewlines?: boolean, - wrapAtSoftNewlines?: boolean, - screenLine?: boolean, - }, - ): atom$Point, - bufferPositionForScreenPosition( - bufferPosition: atom$PointLike, - options?: { - wrapBeyondNewlines?: boolean, - wrapAtSoftNewlines?: boolean, - screenLine?: boolean, - }, - ): atom$Point, - getVisibleRowRange(): ?[number, number], - - // Decorations - decorateMarker(marker: atom$Marker, decorationParams: DecorateMarkerParams): atom$Decoration, - decorationsForScreenRowRange( - startScreenRow: number, - endScreenRow: number, - ): {[markerId: string]: Array}, - getDecorations(options?: {class?: string, type?: string}): Array, - - // Markers - markBufferPosition(position: atom$PointLike, options?: MarkerOptions): atom$Marker, - markBufferRange(range: atom$RangeLike, options?: MarkerOptions): atom$Marker, - markScreenRange(range: atom$RangeLike, options?: MarkerOptions): atom$Marker, - - // Cursors - getCursors(): Array, - setCursorBufferPosition( - position: atom$PointLike, - options?: { - autoscroll?: boolean, - wrapBeyondNewlines?: boolean, - wrapAtSoftNewlines?: boolean, - screenLine?: boolean, - }): void, - getCursorBufferPosition(): atom$Point, - getCursorScreenPosition(): atom$Point, - getCursorScreenPositions(): Array, - getLastCursor(): atom$Cursor, - moveToBeginningOfLine(): void, - moveToEndOfLine(): void, - moveToBottom(): void, - - // Selections - getSelectedText(): string, - selectAll(): void, - getSelectedBufferRange(): atom$Range, - getSelectedBufferRanges(): Array, - getSelections(): Array, - selectToBufferPosition(point: atom$Point): void, - setSelectedBufferRange( - bufferRange: atom$Range, - options?: { - reversed?: boolean, - preserveFolds?: boolean, - }, - ): void, - setSelectedBufferRanges( - bufferRanges: Array, - options?: { - reversed?: boolean, - preserveFolds?: boolean, - }, - ): void, - - // Folds - unfoldAll(): void, - - // Searching and Replacing - scanInBufferRange( - regex: RegExp, - range: atom$Range, - iterator: (foundMatch: { - match: mixed, - matchText: string, - range: atom$Range, - stop: () => mixed, - replace: (replaceWith: string) => mixed, - }) => mixed - ): void, - - scan( - regex: RegExp, - iterator: (foundMatch: { - match: mixed, - matchText: string, - range: atom$Range, - stop: () => mixed, - replace: (replaceWith: string) => mixed, - }) => mixed - ): void, - - // Tab Behavior - // Soft Wrap Behavior - // Indentation - indentationForBufferRow(bufferRow: number): number, - setTabLength(tabLength: number): void, - setSoftTabs(softTabs: boolean): void, - - lineTextForBufferRow(bufferRow: number): string, - - // Grammars - getGrammar(): atom$Grammar, - setGrammar(grammar: ?atom$Grammar): void, - - // Clipboard Operations - pasteText: (options?: Object) => void, - - // Managing Syntax Scopes - scopeDescriptorForBufferPosition( - bufferPosition: atom$PointLike, - ): atom$ScopeDescriptor, - - // Gutter - addGutter(options: { - name: string, - priority?: number, - visible?: boolean, - }): atom$Gutter, - observeGutters(callback: (gutter: atom$Gutter) => void): IDisposable, - gutterWithName(name: string): ?atom$Gutter, - - // Scrolling the TextEditor - scrollToBufferPosition( - position: atom$Point | [?number, ?number], - options?: {center?: boolean} - ): void, - scrollToScreenPosition( - position: atom$Point | [?number, ?number], - options?: {center?: boolean} - ): void, - scrollToBottom(): void, - scrollToTop(): void, - - // TextEditor Rendering - getPlaceholderText(): string, - setPlaceholderText(placeholderText: string): void, - - // This is undocumented, but Nuclide uses it in the AtomTextEditor wrapper. - setLineNumberGutterVisible(lineNumberGutterVisible: boolean): void, - - // Editor Options - setSoftWrapped(softWrapped: boolean): void, - - isFoldedAtBufferRow(row: number): boolean, - getLastBufferRow(): number, - - // Undocumented properties - presenter: ?atom$TextEditorPresenter, - - // Undocumented Methods - getDefaultCharWidth(): number, - getLineHeightInPixels(): number, - moveToTop(): void, - tokenForBufferPosition(position: atom$Point | [?number, ?number]): atom$Token, - onDidConflict(callback: () => void): IDisposable, - serialize: () => mixed, -} - -/** - * This is not part of the official Atom 1.0 API. Nevertheless, we need to reach into this object - * via `atom$TextEditorElement` to do some things that we have no other way to do. - */ -declare class atom$TextEditorComponent { - domNode: HTMLElement, - scrollViewNode: HTMLElement, - presenter: atom$TextEditorPresenter, - linesComponent: atom$LinesComponent, - pixelPositionForScreenPosition( - screenPosition: atom$Point, - clip?: boolean, - ): {top: number, left: number}, - screenPositionForMouseEvent(event: MouseEvent): atom$Point, - pixelPositionForMouseEvent( - event: MouseEvent, - linesClientRect?: {top: number, left: number, bottom: number, right: number}, - ): {top: number, left: number, bottom: number, right: number}, - invalidateBlockDecorationDimensions(decoration: atom$Decoration): void, -} - -/** - * This is not part of the official Atom 1.0 API. Nevertheless, we need to reach into this object - * via `atom$TextEditorComponent` to do some things that we have no other way to do. - */ -declare class atom$TextEditorPresenter { - startBlinkingCursors: () => void, - stopBlinkingCursors(visible: boolean): void, - updateLineNumberGutterState(): void, -} - -/** - * This is not part of the official Atom 1.0 API. Nevertheless, we need it to access - * the deepest dom element receiving DOM events. - */ -declare class atom$LinesComponent { - domNode: HTMLElement, - getDomNode(): HTMLElement, -} - -/** - * This is not part of the official Atom 1.0 API, but it really should be. This is the element that - * is returned when you run `atom.views.getView()`. - */ -declare class atom$TextEditorElement extends HTMLElement { - component: ?atom$TextEditorComponent, - getModel(): atom$TextEditor, - setModel(model: atom$TextEditor): void, - pixelPositionForBufferPosition( - bufferPosition: atom$PointLike, - ): {top: number, left: number}, - pixelPositionForScreenPosition(screenPosition: atom$Point): { - left: number, - top: number, - }, - - setScrollTop(scrollTop: number): void, - getScrollTop(): number, - - setScrollLeft(scrollLeft: number): void, - getScrollLeft(): number, - - getScrollHeight(): number, - - onDidChangeScrollTop(callback: (scrollTop: number) => mixed): IDisposable, - onDidChangeScrollLeft(callback: (scrollLeft: number) => mixed): IDisposable, - - // Called when the editor is attached to the DOM. - onDidAttach(callback: () => mixed): IDisposable, - // Called when the editor is detached from the DOM. - onDidDetach(callback: () => mixed): IDisposable, - - // Undocumented Methods - - // `undefined` means no explicit width. `null` sets a zero width (which is almost certainly a - // mistake) so we don't allow it. - setWidth(width: number | void): void, -} - -declare class atom$ViewProvider { - modelConstructor: Function, -} - -declare class atom$ViewRegistry { - // Methods - addViewProvider( - modelConstructor: any, - createView?: (...args: any[]) => ?HTMLElement - ): IDisposable, - getView(textEditor: atom$TextEditor): atom$TextEditorElement, - getView(notification: atom$Notification): HTMLElement, - getView(gutter: atom$Gutter): HTMLElement, - getView(panel: atom$Panel): HTMLElement, - getView(workspace: atom$Workspace): HTMLElement, - getView(object: Object): HTMLElement, - providers: Array, -} - -type atom$WorkspaceAddPanelOptions = { - item: Object, - visible?: boolean, - priority?: number, -}; - -type atom$TextEditorParams = { - buffer?: atom$TextBuffer, - lineNumberGutterVisible?: boolean, -}; - -type DestroyPaneItemEvent = { - item: atom$PaneItem, - pane: atom$Pane, - index: number, -}; - -type AddPaneItemEvent = { - item: atom$PaneItem, - pane: atom$Pane, - index: number, -}; - -type OnDidOpenEvent = { - uri: string, - item: mixed, - pane: atom$Pane, - index: number, -}; - -type AddTextEditorEvent = { - textEditor: atom$TextEditor, - pane: atom$Pane, - index: number, -}; - -declare class atom$Workspace { - // Event Subscription - observePanes(cb: (pane: atom$Pane) => void): IDisposable, - observeTextEditors(callback: (editor: atom$TextEditor) => mixed): IDisposable, - onDidAddTextEditor(callback: (event: AddTextEditorEvent) => mixed): IDisposable, - onDidChangeActivePaneItem(callback: (item: mixed) => mixed): IDisposable, - onDidDestroyPaneItem(callback: (event: DestroyPaneItemEvent) => mixed): IDisposable, - onDidAddPaneItem(callback: (event: AddPaneItemEvent) => mixed): IDisposable, - observeActivePaneItem(callback: (item: ?mixed) => mixed): IDisposable, - onDidStopChangingActivePaneItem(callback: (item: ?mixed) => mixed): IDisposable, - observePaneItems(callback: (item: mixed) => mixed): IDisposable, - onWillDestroyPaneItem( - callback: (event: {item: mixed, pane: mixed, index: number}) => mixed - ): IDisposable, - onDidOpen(callback: (event: OnDidOpenEvent) => mixed): IDisposable, - - // Opening - open( - uri?: string, - options?: { - activePane?: boolean, - initialLine?: number, - initialColumn?: number, - pending?: boolean, - split?: string, - searchAllPanes?: boolean, - } - ): Promise, - openURIInPane( - uri?: string, - pane: atom$Pane, - options?: { - initialLine?: number, - initialColumn?: number, - activePane?: boolean, - searchAllPanes?: boolean, - } - ): Promise, - isTextEditor(item: ?mixed): boolean, - /* Optional method because this was added post-1.0. */ - buildTextEditor: ((params: atom$TextEditorParams) => atom$TextEditor), - /* Optional method because this was added in 1.9.0 */ - handleGrammarUsed?: (grammar: atom$Grammar) => void, - reopenItem(): Promise, - addOpener(callback: (uri: string) => any): IDisposable, - - // Pane Items - getPaneItems(): Array, - getActivePaneItem(): ?Object, - getTextEditors(): Array, - getActiveTextEditor(): ?atom$TextEditor, - - // Panes - getPanes(): Array, - getActivePane(): atom$Pane, - activateNextPane(): boolean, - activatePreviousPane(): boolean, - paneForURI(uri: string): atom$Pane, - paneForItem(item: mixed): ?atom$Pane, - - // Panels - getBottomPanels(): Array, - addBottomPanel(options: atom$WorkspaceAddPanelOptions): atom$Panel, - getLeftPanels(): Array, - addLeftPanel(options: atom$WorkspaceAddPanelOptions): atom$Panel, - getRightPanels(): Array, - addRightPanel(options: atom$WorkspaceAddPanelOptions): atom$Panel, - getTopPanels(): Array, - addTopPanel(options: atom$WorkspaceAddPanelOptions): atom$Panel, - getModalPanels(): Array, - addModalPanel(options: atom$WorkspaceAddPanelOptions): atom$Panel, - - // Searching and Replacing - - destroyActivePaneItemOrEmptyPane(): void, - destroyActivePaneItem(): void, - - // Undocumented properties - paneContainer: atom$PaneContainer, -} - -/** - * Extended Classes - */ - -declare class atom$BufferedNodeProcess { } - -declare class atom$BufferedProcess { - // Event Subscription - onWillThrowError( - callback: (errorObject: {error: Object, handle: mixed}) => mixed - ): IDisposable, - // Helper Methods - kill(): void, -} - -declare class atom$Clipboard { - // Methods - write(text: string, metadata?: mixed): void, - read(): string, - readWithMetadata(): { - metadata: ?mixed, - text: string, - }, -} - -declare class atom$ContextMenuManager { - add(itemsBySelector: {[cssSelector: string]: Array}): IDisposable, - itemSets: Array, - - // Undocumented methods - showForEvent(event: Event): void, - templateForEvent(event: Event): Array, -} - -declare class atom$ContextMenuItemSet { - items: Array, - selector: string, -} - -type atom$ContextMenuItem = { - command?: string, - created?: (event: MouseEvent) => void, - enabled?: boolean, - label?: string, - shouldDisplay?: (event: MouseEvent) => boolean, - submenu?: Array, - type?: string, - visible?: boolean, -}; - -type atom$Deserializer = { - name: string, - deserialize: (state: Object) => mixed, -}; - -declare class atom$DeserializerManager { - add(...deserializers: Array): IDisposable, - deserialize(state: Object, params?: Object): mixed, -} - -// Apparently it can sometimes include a `code` property. -declare class atom$GetEntriesError extends Error { - code?: string, -} - -declare class atom$Directory { - symlink: boolean, - - // Construction - create(mode?: number): Promise, - - // Event Subscription - onDidChange(callback: () => mixed): IDisposable, - - // Directory Metadata - isFile(): boolean, - isDirectory(): boolean, - exists():Promise, - - // Managing Paths - getPath(): string, - getBaseName(): string, - relativize(fullPath: string): string, - - // Event Subscription - onDidRename(callback: () => void): IDisposable, - onDidDelete(callback: () => void): IDisposable, - - // Traversing - getParent(): atom$Directory, - getFile(filename: string): atom$File, - getSubdirectory(dirname: string): atom$Directory, - getEntries( - callback: ( - error: ?atom$GetEntriesError, - entries: ?Array, - ) => mixed): void, - contains(path: string): boolean, -} - -declare class atom$File { - symlink: boolean, - - // Construction - create(): Promise, - - // Event Subscription - onDidChange(callback: () => mixed): IDisposable, - - // File Metadata - isFile(): boolean, - isDirectory(): boolean, - exists(): boolean, - setEncoding(encoding: string): void, - getEncoding(): string, - - // Event Subscription - onDidRename(callback: () => void): IDisposable, - onDidDelete(callback: () => void): IDisposable, - onDidChange(callback: () => void): IDisposable, - - // Managing Paths - getPath(): string, - getBaseName(): string, - - // Traversing - getParent(): atom$Directory, - - // Reading and Writing - read(flushCache?: boolean): Promise, - write(text: string): Promise, - writeSync(text: string): void, -} - -declare class atom$GitRepository extends atom$Repository { - // Unofficial API. - statuses: {[filePath: string]: number}, - // Return the `git-utils` async repo. - getRepo(): atom$GitRepositoryInternal, -} - -declare class atom$Grammar { - name: string, - scopeName: string, - tokenizeLines(text: string): Array>, -} - -type atom$GrammarToken = { - value: string, - scopes: Array, -}; - -declare class atom$GrammarRegistry { - // Event Subscription - onDidAddGrammar(callback: (grammar: atom$Grammar) => void): IDisposable, - - // Managing Grammars - grammarForScopeName(scopeName: string): ?atom$Grammar, - removeGrammarForScopeName(scopeName: string): ?atom$Grammar, - loadGrammarSync(grammarPath: string): atom$Grammar, - selectGrammar(filePath: string, fileContents: string): atom$Grammar, - - // Private API - clear(): IDisposable, -} - -type atom$KeyBinding = Object; - -declare class atom$KeymapManager { - - // Event Subscription - onDidMatchBinding(callback: (event: { - keystrokes: string, - binding: atom$KeyBinding, - keyboardEventTarget: HTMLElement, - }) => mixed): IDisposable, - - onDidPartiallyMatchBinding(callback: (event: { - keystrokes: string, - partiallyMatchedBindings: atom$KeyBinding, - keyboardEventTarget: HTMLElement, - }) => mixed): IDisposable, - - onDidFailToMatchBinding(callback: (event: { - keystrokes: string, - partiallyMatchedBindings: atom$KeyBinding, - keyboardEventTarget: HTMLElement, - }) => mixed): IDisposable, - - onDidFailToReadFile(callback: (error: { - message: string, - stack: string, - }) => mixed): IDisposable, - - // Adding and Removing Bindings - add(source: string, bindings: Object): void, - - // Accessing Bindings - getKeyBindings(): Array, - findKeyBindings(params: { - keystrokes?: string, - command: string, - target?: HTMLElement, - }): Array, - - // Managing Keymap Files - loadKeymap(path: string, options?: {watch: boolean}): void, - watchKeymap(path: string): void, - - // Managing Keyboard Events - handleKeyboardEvent(event: Event): void, - keystrokeForKeyboardEvent(event: Event): string, - getPartialMatchTimeout(): number, - - static buildKeydownEvent( - key: string, - options: { - target: HTMLElement, - alt?: boolean, - cmd?: boolean, - ctrl?: boolean, - shift?: boolean, - }, - ): Event, -} - -declare class atom$MenuManager { - add(items: Array): IDisposable, - update(): void, - - // Private API - template: Array, -} - -declare class atom$Project { - // Event Subscription - onDidChangePaths(callback: (projectPaths: Array) => mixed): IDisposable, - onDidAddBuffer(callback: (buffer: atom$TextBuffer) => mixed): IDisposable, - - // Accessing the git repository - getRepositories(): Array, - repositoryForDirectory(directory: atom$Directory): Promise, - - // Managing Paths - getPaths(): Array, - addPath(projectPath: string): void, - setPaths(paths: Array): void, - removePath(projectPath: string): void, - getDirectories(): Array, - relativizePath(): Array, // [projectPath: ?string, relativePath: string] - relativize(filePath: string): string, - - // Private API - findBufferForPath(path: string): ?atom$TextBuffer, - addBuffer(buffer: atom$TextBuffer): void, - removeBuffer(buffer: atom$TextBuffer): void, - getBuffers(): Array, -} - -type TextBufferScanIterator = (arg: { - match: Array, - matchText: string, - range: atom$Range, - stop(): void, - replace(replacement: string): void, -}) => void; - -// This happens to be a number but it would be better if the type could be entirely opaque. All you -// need to know is that if something needs a checkpoint you should only pass it values received from -// TextBuffer::createCheckpoint -type atom$TextBufferCheckpoint = number; - -// TextBuffer did-change/will-change -type atom$TextEditEvent = { - oldRange: atom$Range, - newRange: atom$Range, - oldText: string, - newText: string, -}; - -declare class atom$TextBuffer { - file: ?atom$File, - - // Mixin - static deserialize: (state: Object, params: Object) => mixed, - - // Events - onWillChange(callback: (event: atom$TextEditEvent) => mixed): IDisposable, - onDidChange(callback: (event: atom$TextEditEvent) => mixed): IDisposable, - onDidStopChanging(callback: () => mixed): IDisposable, - onDidConflict(callback: () => mixed): IDisposable, - onDidChangeModified(callback: () => mixed): IDisposable, - onDidUpdateMarkers(callback: () => mixed): IDisposable, - onDidCreateMarker(callback: () => mixed): IDisposable, - onDidChangePath(callback: () => mixed): IDisposable, - onDidChangeEncoding(callback: () => mixed): IDisposable, - onWillSave(callback: () => mixed): IDisposable, - onDidSave(callback: () => mixed): IDisposable, - onDidDelete(callback: () => mixed): IDisposable, - onWillReload(callback: () => mixed): IDisposable, - onDidReload(callback: () => mixed): IDisposable, - onDidDestroy(callback: () => mixed): IDisposable, - onWillThrowWatchError(callback: () => mixed): IDisposable, - - // File Details - setPath(filePath: string): void, - getPath(): ?string, - setEncoding(encoding: string): void, - getEncoding(): string, - getUri(): string, - getId(): string, - - // Reading Text - isEmpty(): boolean, - getText(): string, - getTextInRange(range: atom$RangeLike): string, - getLineCount(): number, - getLines(): Array, - getLastLine(): string, - lineForRow(row: number): string, - lineEndingForRow(row: number): string, - lineLengthForRow(row: number): number, - isRowBlank(row: number): boolean, - previousNonBlankRow(startRow: number): ?number, - nextNonBlankRow(startRow: number): ?number, - - // Mutating Text - setText: (text: string) => atom$Range, - setTextInRange(range: atom$RangeLike, text: string, options?: Object): atom$Range, - setTextViaDiff(text: string): void, - insert( - position: atom$Point, - text: string, - options?: { - normalizeLineEndings?: boolean, - undo?: string, - }, - ): atom$Range, - append(text: string, options: ?{ - normalizeLineEndings?: boolean, - undo?: string, - }): atom$Range, - delete(range: atom$Range): atom$Range, - deleteRows(startRow: number, endRow: number): atom$Range, - - // History - undo(): void, - redo(): void, - transact(fn: () => mixed, _: void): void, - transact(groupingInterval: number, fn: () => mixed): void, - clearUndoStack(): void, - createCheckpoint(): atom$TextBufferCheckpoint, - revertToCheckpoint(checkpoint: atom$TextBufferCheckpoint): boolean, - groupChangesSinceCheckpoint(checkpoint: atom$TextBufferCheckpoint): boolean, - // TODO describe the return type more precisely. - getChangesSinceCheckpoint(checkpoint: atom$TextBufferCheckpoint): Array, - - // Search And Replace - scanInRange(regex: RegExp, range: atom$Range, iterator: TextBufferScanIterator): void, - backwardsScanInRange(regex: RegExp, range: atom$Range, iterator: TextBufferScanIterator): void, - - // Buffer Range Details - getLastRow(): number, - getRange(): atom$Range, - rangeForRow(row: number, includeNewLine?: boolean): atom$Range, - - // Position/Index mapping - characterIndexForPosition(position: atom$PointLike): number, - positionForCharacterIndex(index: number): atom$Point, - - // Buffer Operations - reload(): void, - load(): Promise, - save(): void, - - isInConflict(): boolean, - isModified(): boolean, - - // Private APIs - cachedDiskContents: ?string, - emitter: atom$Emitter, - refcount: number, - loaded: boolean, - changeCount: number, - wasModifiedBeforeRemove: boolean, - finishLoading(): atom$TextBuffer, - updateCachedDiskContents(flushCache?: boolean, callback?: () => mixed): Promise, - emitModifiedStatusChanged(changed: boolean): void, - destroy(): void, - isDestroyed(): boolean, - applyChange: () => void, -} - -declare class atom$Notification { - // Event Subscription - onDidDismiss(callback: () => mixed): IDisposable, - onDidDisplay(callback: () => mixed): IDisposable, - - // Methods - getType(): string, - getMessage(): string, - getOptions(): Object, - dismiss(): void, -} - -type atom$NotificationButton = { - text: string, - className?: string, - onDidClick?: () => mixed, -}; - -type atom$NotificationOptions = { - detail?: string, - dismissable?: boolean, - description?: string, - icon?: string, - buttons?: Array, -}; - -declare class atom$NotificationManager { - // Events - onDidAddNotification(callback: (notification: atom$Notification) => void): IDisposable, - - // Adding Notifications - addSuccess(message: string, options?: atom$NotificationOptions): atom$Notification, - addInfo(message: string, options?: atom$NotificationOptions): atom$Notification, - addWarning(message: string, options?: atom$NotificationOptions): atom$Notification, - addError(message: string, options?: atom$NotificationOptions): atom$Notification, - addFatalError(message: string, options?: atom$NotificationOptions): atom$Notification, - - // Getting Notifications - getNotifications(): Array, -} - -// The items in this declaration are available off of `require('atom')`. -// This list is not complete. -declare module 'atom' { - declare var BufferedNodeProcess: typeof atom$BufferedNodeProcess; - declare var BufferedProcess: typeof atom$BufferedProcess; - declare var CompositeDisposable: typeof atom$CompositeDisposable; - declare var Directory: typeof atom$Directory; - declare var Disposable: typeof atom$Disposable; - declare var Emitter: typeof atom$Emitter; - declare var File: typeof atom$File; - declare var GitRepository: typeof atom$GitRepository; - declare var Notification: typeof atom$Notification; - declare var Point: typeof atom$Point; - declare var Range: typeof atom$Range; - declare var TextBuffer: typeof atom$TextBuffer; - declare var TextEditor: typeof atom$TextEditor; -} - -// Make sure that common types can be referenced without the `atom$` prefix -// in type declarations. -declare var Cursor: typeof atom$Cursor; -declare var Panel: typeof atom$Panel; -declare var TextEditor: typeof atom$TextEditor; - -type atom$UnhandledErrorEvent = { - originalError: Object, - message: string, - url: string, - line: number, - column: number, -}; - -// The properties of this type match the properties of the `atom` global. -// This list is not complete. -type AtomGlobal = { - // Properties - appVersion: string, - atomScriptMode: ?boolean, // Added by nuclide-atom-script. - clipboard: atom$Clipboard, - commands: atom$CommandRegistry, - config: atom$Config, - contextMenu: atom$ContextMenuManager, - applicationDelegate: atom$applicationDelegate, - deserializers: atom$DeserializerManager, - grammars: atom$GrammarRegistry, - keymaps: atom$KeymapManager, - menu: atom$MenuManager, - notifications: atom$NotificationManager, - packages: atom$PackageManager, - styles: atom$StyleManager, - themes: atom$ThemeManager, - textEditors: atom$TextEditorRegistry, - tooltips: atom$TooltipManager, - views: atom$ViewRegistry, - workspace: atom$Workspace, - project: atom$Project, - devMode: boolean, - - // Event Subscription - onWillThrowError(callback: (event: atom$UnhandledErrorEvent) => mixed): IDisposable, - onDidThrowError(callback: (event: atom$UnhandledErrorEvent) => mixed): IDisposable, - - // Atom Details - inDevMode(): boolean, - inSafeMode(): boolean, - inSpecMode(): boolean, - getVersion(): string, - isReleasedVersion(): boolean, - getWindowLoadTime(): number, - - // This is an undocumented way to reach the Electron BrowserWindow. - // Use `electron.remote.getCurrentWindow` instead. - getCurrentWindow: void, - - // Messaging the User - confirm(options: { - buttons?: Array | {[buttonName: string]: () => mixed}, - detailedMessage?: string, - message: string, - }): ?number, - - open(params: { - pathsToOpen?: Array, - newWindow?: boolean, - devMode?: boolean, - safeMode?: boolean, - }): void, - reload(): void, - - // Undocumented Methods - getConfigDirPath(): string, - showSaveDialogSync(options: Object): string, - loadState(): Promise, - getLoadSettings(): Object, -}; - -declare var atom: AtomGlobal; - -type RepositoryDidChangeStatusCallback = (event: {path: string, pathStatus: number}) => mixed; -type RepositoryLineDiff = { - oldStart: number, - newStart: number, - oldLines: number, - newLines: number, -}; - -// Taken from the interface of [`GitRepository`][1], which is also implemented by -// `HgRepositoryClient`. -// -// [1]: https://github.com/atom/atom/blob/v1.7.3/src/git-repository.coffee -declare class atom$Repository { - // Event Subscription - onDidChangeStatus: (callback: RepositoryDidChangeStatusCallback) => IDisposable, - onDidChangeStatuses: (callback: () => mixed) => IDisposable, - - // Repository Details - getType: () => string, - getPath: () => string, - getWorkingDirectory: () => string, - isProjectAtRoot: () => boolean, - relativize: (aPath: string) => string, - - // Reading Status - isPathModified: (aPath: string) => boolean, - isPathNew: (aPath: string) => boolean, - isPathIgnored: (aPath: string) => boolean, - getDirectoryStatus: (aPath: string) => number, - getPathStatus: (aPath: string) => number, - getCachedPathStatus: (aPath: string) => ?number, - isStatusModified: (status: number) => boolean, - isStatusNew: (status: number) => boolean, - refreshStatus: () => Promise, - - // Retrieving Diffs - getDiffStats: (filePath: string) => {added: number, deleted: number}, - getLineDiffs: (aPath: string, text: string) => Array, - - // Checking Out - checkoutHead: (aPath: string) => boolean, - checkoutReference: (reference: string, create: boolean) => Promise, - - // Event Subscription - onDidDestroy(callback: () => mixed): IDisposable, - isDestroyed(): boolean, -} - -declare class atom$GitRepositoryInternal { - // Reading Status - isStatusModified: (status: number) => boolean, - isStatusNew: (status: number) => boolean, - isStatusIgnored: (status: number) => boolean, - isStatusStaged: (status: number) => boolean, - isStatusDeleted: (status: number) => boolean, -} - -// One of text or snippet is required. -// TODO(hansonw): use a union + intersection type -type atom$AutocompleteSuggestion = { - text?: string, - snippet?: string, - displayText?: string, - replacementPrefix?: string, - type?: ?string, - leftLabel?: ?string, - leftLabelHTML?: ?string, - rightLabel?: ?string, - rightLabelHTML?: ?string, - className?: ?string, - iconHTML?: ?string, - description?: ?string, - descriptionMoreURL?: ?string, -}; - -type atom$AutocompleteRequest = { - editor: TextEditor, - bufferPosition: atom$Point, - scopeDescriptor: string, - prefix: string, - activatedManually?: boolean, -}; - -type atom$AutocompleteProvider = { - selector: string, - getSuggestions: ( - request: atom$AutocompleteRequest, - ) => Promise>, - disableForSelector?: string, - inclusionPriority?: number, - excludeLowerPriority?: boolean, -}; - -// Undocumented API. -declare class atom$Token { - value: string, - matchesScopeSelector(selector: string): boolean, -} - -declare class atom$Selection { - clear(): void, - getText(): string, - insertText( - text: string, - options?: { - select?: boolean, - autoIndent?: boolean, - autoIndentNewLine?: boolean, - autoDecreaseIdent?: boolean, - normalizeLineEndings?: boolean, - undo?: boolean, - }, - ): string, -} diff --git a/flow-libs/chrome-devtools-protocol.js.flow b/flow-libs/chrome-devtools-protocol.js.flow deleted file mode 100644 index f47a7b4083..0000000000 --- a/flow-libs/chrome-devtools-protocol.js.flow +++ /dev/null @@ -1,48 +0,0 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the license found in the LICENSE file in - * the root directory of this source tree. - * - * @flow - */ - -//------------------------------------------------------------------------------ -// Runtime domain types. -//------------------------------------------------------------------------------ - -// description wins over value in display -type Runtime$RemoteObject = { - className?: string, - description?: string, - objectId?: Runtime$RemoteObjectId, - subtype?: 'array' | 'date' | 'node' | 'null' | 'regexp', - type: 'boolean' | 'function' | 'number' | 'object' | 'string' | 'undefined', - value?: mixed, -}; - -type Runtime$RemoteObjectId = string; - -type Runtime$PropertyDescriptor = { - configurable: boolean, - enumerable: boolean, - get?: Runtime$RemoteObject, - name: string, - set?: Runtime$RemoteObject, - value?: Runtime$RemoteObject, - wasThrown?: boolean, - writable?: boolean, -}; - -//------------------------------------------------------------------------------ -// Debugger domain types. -//------------------------------------------------------------------------------ - -// scope.object.description shows on RHS -type Debugger$Scope = { - object: Runtime$RemoteObject, - type: Debugger$ScopeType, -}; - -type Debugger$ScopeType = 'catch' | 'closure' | 'global' | 'local' | 'with'; diff --git a/flow-libs/connect.js.flow b/flow-libs/connect.js.flow deleted file mode 100644 index 8fdd6ff0bd..0000000000 --- a/flow-libs/connect.js.flow +++ /dev/null @@ -1,90 +0,0 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the license found in the LICENSE file in - * the root directory of this source tree. - * - * @flow - */ - -declare class connect$Error extends Error { - code?: number, -} - -type connect$ServerHandle = connect$HandleFunction | http$fixed$Server; -type connect$SimpleHandleFunction = - (req: http$fixed$IncomingMessage, res: http$fixed$ServerResponse) => mixed; -type connect$NextHandleFunction = - (req: http$fixed$IncomingMessage, res: http$fixed$ServerResponse, next: Function) => mixed; -type connect$ErrorHandleFunction = (err: ?connect$Error, req: http$fixed$IncomingMessage, - res: http$fixed$ServerResponse, next: Function) => mixed; -type connect$HandleFunction = - connect$SimpleHandleFunction | connect$NextHandleFunction | connect$ErrorHandleFunction; - -type connect$ServerStackItem = { - route: string, - handle: connect$ServerHandle, -}; - -declare class connect$Server { - (req: http$fixed$IncomingMessage, res: http$fixed$ServerResponse, next?: Function): void, - - route: string, - stack: Array, - - /** - * Utilize the given middleware `handle` to the given `route`, - * defaulting to _/_. This "route" is the mount-point for the - * middleware, when given a value other than _/_ the middleware - * is only effective when that segment is present in the request's - * pathname. - * - * For example if we were to mount a function at _/admin_, it would - * be invoked on _/admin_, and _/admin/settings_, however it would - * not be invoked for _/_, or _/posts_. - * - * @public - */ - use(fn: connect$HandleFunction): connect$Server, - use(route: string, fn: connect$HandleFunction): connect$Server, - - /** - * Handle server requests, punting them down - * the middleware stack. - * - * @private - */ - handle(req: http$fixed$IncomingMessage, res: http$fixed$ServerResponse, next: Function): void, - - /** - * Listen for connections. - * - * This method takes the same arguments - * as node's `http$fixed$Server#listen()`. - * - * HTTP and HTTPS: - * - * If you run your application both as HTTP - * and HTTPS you may wrap them individually, - * since your Connect "server" is really just - * a JavaScript `Function`. - * - * var connect = require('connect') - * , http = require('http') - * , https = require('https'); - * - * var app = connect(); - * - * http$fixed$createServer(app).listen(80); - * https.createServer(options, app).listen(443); - * - * @api public - */ - listen(port: number, hostname?: string, backlog?: number, callback?: Function): http$fixed$Server, - listen(port: number, hostname?: string, callback?: Function): http$fixed$Server, - listen(path: string, callback?: Function): http$fixed$Server, - listen(handle: any, listeningListener?: Function): http$fixed$Server, -} - -type connect$module = () => connect$Server; diff --git a/flow-libs/electron.js.flow b/flow-libs/electron.js.flow deleted file mode 100644 index 30f692072a..0000000000 --- a/flow-libs/electron.js.flow +++ /dev/null @@ -1,718 +0,0 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the license found in the LICENSE file in - * the root directory of this source tree. - * - * @flow - */ - -// The properties on this module depend on whether the importer is the main -// process or a renderer process. -declare module 'electron' { - // Main process: - declare var app: ?electron$app; - declare var autoUpdater: ?electron$autoUpdater; - declare var BrowserWindow: ?typeof electron$BrowserWindow; - declare var contentTracing: ?electron$contentTracing; - declare var dialog: ?electron$dialog; - declare var globalShortcut: ?electron$globalShortcut; - declare var ipcMain: ?electron$IpcMain; - declare var Menu: ?typeof electron$Menu; - declare var MenuItem: ?typeof electron$MenuItem; - declare var powerMonitor: ?electron$powerMonitor; - declare var powerSaveBlocker: ?electron$powerSaveBlocker; - declare var protocol: ?electron$protocol; - declare var session: ?electron$session; - declare var electron$Tray: ?typeof electron$Tray; - declare var webContents: ?electron$webContents; - - // Renderer process: - declare var desktopCapturer: ?electron$desktopCapturer; - declare var ipcRenderer: ?electron$IpcRenderer; - declare var remote: ?electron$remote; - declare var webFrame: ?electron$webFrame; - - // Both: - declare var clipboard: electron$clipboard; - declare var crashReporter: electron$crashReporter; - declare var nativeImage: electron$nativeImage; - declare var screen: electron$Screen; - declare var shell: electron$shell; - - declare type electron$BrowserWindow = electron$BrowserWindow; - declare type electron$Menu = electron$Menu; - declare type electron$MenuItem = electron$MenuItem; - declare type electron$NativeImage = electron$NativeImage; - declare type electron$Screen = electron$Screen; - declare type electron$WebContents = electron$WebContents; -} - -// very common struct -type electron$rect = { - x: number, - y: number, - width: number, - height: number, -}; - -//------------------------------------------------------------------------------ -// Custom DOM Elements -//------------------------------------------------------------------------------ - -/** - * https://github.com/electron/electron/blob/master/docs/api/file-object.md - */ - -// HTML5 File API but with a `path` attribute added. - -/** - * https://github.com/electron/electron/blob/master/docs/api/web-view-tag.md - */ - -declare class WebviewElement extends HTMLElement { - src: string, - nodeintegration: boolean, - disablewebsecurity: boolean, - - executeJavaScript(code: string, userGesture: ?boolean): void, - getTitle(): string, - // This used to be `getUrl`, but the old version was dropped in the electron bundled with Atom - // 1.12, and the new version exists at least in Atom 1.10.2 onward. - getURL(): string, - // Not sure when this was introduced - stop?: () => void, - insertCSS(code: string): void, - send(): void, - openDevTools(): void, -} - -/** - * https://github.com/electron/electron/blob/master/docs/api/window-open.md - */ - -// window.open - -//------------------------------------------------------------------------------ -// Modules for the Main Process -//------------------------------------------------------------------------------ - -/** - * https://github.com/electron/electron/blob/master/docs/api/app.md - */ - -type electron$app = { - quit(): void, - exit(exitCode?: number): void, - relaunch(options?: {args?: Array, execPath?: string}): void, - isReady(): boolean, - focus(): void, - getAppPath(): string, - getPath(name: string): string, - setPath(name: string, path: string): void, - getVersion(): string, - getName(): string, - setName(name: string): void, - getLocale(): string, - makeSingleInstance(callback: (argv: Array, workingDirectory: string) => void): boolean, - releaseSingleInstance(): void, - disableHardwareAcceleration(): void, -}; - -/** - * https://github.com/electron/electron/blob/master/docs/api/auto-updater.md - */ - -type electron$autoUpdater = {}; - -/** - * https://github.com/electron/electron/blob/master/docs/api/browser-window.md - */ - -type electron$BrowserWindowOptions = { - width?: number, - height?: number, - x?: number, - y?: number, - useContentSize?: boolean, - center?: boolean, - minWidth?: number, - minHeight?: number, - maxWidth?: number, - maxHeight?: number, - resizable?: boolean, - movable?: boolean, - minimizable?: boolean, - maximizable?: boolean, - closable?: boolean, - focusable?: boolean, - alwaysOnTop?: boolean, - fullscreen?: boolean, - fullscreenable?: boolean, - skipTaskbar?: boolean, - kiosk?: boolean, - title?: string, - icon?: electron$NativeImage, - show?: boolean, - frame?: boolean, - parent?: electron$BrowserWindow, - modal?: boolean, - acceptFirstMouse?: boolean, - disableAutoHideCursor?: boolean, - autoHideMenuBar?: boolean, - enableLargerThanScreen?: boolean, - backgroundColor?: string, - hasShadow?: boolean, - darkTheme?: boolean, - transparent?: boolean, - type?: 'desktop' | 'dock' | 'toolbar' | 'splash' | 'notification' | - /* macOS */ 'desktop' | 'textured' | - /* Windows */ 'toolbar', - titleBarStyle?: 'default' | 'hidden' | 'hidden-inset', - thickFrame?: boolean, - webPreferences?: electron$BrowserWindowWebPreferences, -}; - -type electron$BrowserWindowWebPreferences = { - nodeIntegration?: boolean, - preload?: string, - session?: electron$session, - partition?: string, - zoomFactor?: number, - javascript?: boolean, - webSecurity?: boolean, - allowDisplayingInsecureContent?: boolean, - allowRunningInsecureContent?: boolean, - images?: boolean, - textAreasAreResizable?: boolean, - webgl?: boolean, - webaudio?: boolean, - plugins?: boolean, - experimentalFeatures?: boolean, - experimentalCanvasFeatures?: boolean, - scrollBounce?: boolean, - blinkFeatures?: string, - disableBlinkFeatures?: string, - defaultFontFamily?: { - standard?: string, - serif?: string, - sansSerif?: string, - monospace?: string, - }, - defaultFontSize?: number, - defaultMonospaceFontSize?: number, - minimumFontSize?: number, - defaultEncoding?: string, - backgroundThrottling?: boolean, - offscreen?: boolean, -}; - -type electron$BrowserWindowEvents = - | 'page-title-updated' - | 'close' - | 'closed' - | 'unresponsive' - | 'responsive' - | 'blur' - | 'focus' - | 'show' - | 'hide' - | 'ready-to-show' - | 'maximize' - | 'unmaximize' - | 'minimize' - | 'restore' - | 'resize' - | 'move' - | 'moved' - | 'enter-full-screen' - | 'leave-full-screen' - | 'enter-html-full-screen' - | 'leave-html-full-screen' - | 'app-command' // Windows - | 'scroll-touch-begin' // macOS - | 'scroll-touch-end' // macOS - | 'swipe'; // macOS - -type electron$BrowserWindowListener = ( - event: electron$BrowserWindowEvents, - callback: (event: Object, ...args: Array) => void, -) => electron$BrowserWindow; - -declare class electron$BrowserWindow { - constructor(options: electron$BrowserWindowOptions): void, - on: electron$BrowserWindowListener, - once: electron$BrowserWindowListener, - removeAllListeners(event?: electron$BrowserWindowEvents): electron$BrowserWindow, - removeListener(event?: electron$BrowserWindowEvents, callback: Function): electron$BrowserWindow, - - static getAllWindows(): Array, - static getFocusedWindow(): ?electron$BrowserWindow, - static fromWebContents(webContents: electron$WebContents): ?electron$BrowserWindow, - static fromId(id: number): ?electron$BrowserWindow, - static addDevToolsExtension(path: string): void, - static removeDevToolsExtension(name: string): void, - static getDevToolsExtensions(): {[name: string]: {[name: string]: string}}, - - webContents: electron$WebContents, - id: string, - destroy(): void, - close(): void, - focus(): void, - blur(): void, - isFocused(): boolean, - show(): void, - showInactive(): void, - hide(): void, - isVisible(): boolean, - isModal(): boolean, - maximize(): void, - unmaximize(): void, - isMaximized(): boolean, - minimize(): void, - restore(): void, - isMinimized(): boolean, - setFullScreen(flag: boolean): void, - isFullScreen(): boolean, - setAspectRatio(aspectRatio: number, extraSize?: {width: number, height: number}): void, // macOS - setBounds(options: electron$rect, /* macOS */ animate?: boolean): void, - getBounds(): electron$rect, - setSize(width: number, height: number, /* macOS */ animate?: boolean): void, - getSize(): [number, number], - setContentSize(width: number, height: number, /* macOS */ animate?: boolean): void, - getContentSize(): [number, number], - setMinimumSize(width: number, height: number): void, - getMinimumSize(): [number, number], - setMaximumSize(width: number, height: number): void, - getMaximumSize(): [number, number], - setResizable(resizable: boolean): void, - isResizable(): boolean, - setMovable(movable: boolean): void, // macOS Windows - isMovable(): boolean, // macOS Windows - setMinimizable(minimizable: boolean): void, // macOS Windows - isMinimizable(): boolean, // macOS Windows - setMaximizable(maximizable: boolean): void, // macOS Windows - isMaximizable(): boolean, // macOS Windows - setFullScreenable(fullscreenable: boolean): void, - isFullScreenable(): boolean, - setClosable(closable: boolean): void, // macOS Windows - isClosable(): boolean, // macOS Windows - setAlwaysOnTop(flag: boolean): void, - isAlwaysOnTop(): boolean, - center(): void, - setPosition(x: number, y: number, /* macOS */ animate?: boolean): void, - getPosition(): [number, number], - setTitle(title: string): void, - getTitle(): string, - setSheetOffset(offsetY: number, offsetX?: number): void, // macOS - flashFrame(flag: boolean): void, - setSkipTaskbar(skip: boolean): void, - setKiosk(flag: boolean): void, - isKiosk(): boolean, - getNativeWindowHandle(): Buffer, - hookWindowMessage(message: number, callback: Function): void, // Windows - isWindowMessageHooked(message: number): boolean, // Windows - unhookWindowMessage(message: number): void, // Windows - unhookAllWindowMessages(): void, // Windows - setRepresentedFilename(filename: string): void, // macOS - getRepresentedFilename(): string, // macOS - setDocumentEdited(edited: boolean): void, // macOS - isDocumentEdited(): boolean, // macOS - focusOnWebView(): void, - blurWebView(): void, - capturePage(rect: electron$rect, callback: (image: electron$NativeImage) => void): void, - capturePage(callback: (image: electron$NativeImage) => void): void, - loadURL( - url: string, - options?: {httpReferrer?: string, userAgent?: string, extraHeaders?: string}, - ): void, - reload(): void, - setMenu(menu: electron$Menu): void, // Linux Windows - setProgressBar(progress: number): void, - setOverlayIcon(overlay: electron$NativeImage, description: string): void, // Windows - setHasShadow(hasShadow: boolean): void, // macOS - hasShadow(): boolean, // macOS - setThumbarButtons(buttons: Array<{ - icon: electron$NativeImage, - click: Function, - tooltip?: string, - flags?: Array<'enabled' | 'disabled' | 'dismissonclick' | 'nobackground' | - 'hidden' | 'noninteractive'>, - }>): void, // Windows - setThumbnailClip(region: electron$rect): void, // Windows - showDefinitionForSelection(): void, // macOS - setIcon(icon: electron$NativeImage): void, // Windows Linux - setAutoHideMenuBar(hide: boolean): void, - isMenuBarAutoHide(): boolean, - setMenuBarVisibility(visible: boolean): void, - isMenuBarVisible(): boolean, - setVisibleOnAllWorkspaces(visible: boolean): void, - isVisibleOnAllWorkspaces(): boolean, - setIgnoreMouseEvents(ignore: boolean): void, - setContentProtection(enable: boolean): void, // macOS Windows - setFocusable(focusable: boolean): void, // Windows - setParentWindow(parent: electron$BrowserWindow): void, // Linux macOS - getParentWindow(): ?electron$BrowserWindow, - getChildWindows(): Array, -} - -/** - * https://github.com/electron/electron/blob/master/docs/api/content-tracing.md - */ - -type electron$contentTracing = {}; - -/** - * https://github.com/electron/electron/blob/master/docs/api/dialog.md - */ - -type electron$dialog = { - showOpenDialog( - browserWindow?: electron$BrowserWindow, - options: electron$dialogOpenOptions, - callback?: Function, - ): Array, - showSaveDialog( - browserWindow?: electron$BrowserWindow, - options: electron$dialogSaveOptions, - callback?: Function, - ): string, - showMessageBox( - browserWindow?: electron$BrowserWindow, - options: electron$dialogMessageBoxOptions, - callback?: Function, - ): number, - showErrorBox(title: string, content: string): void, -}; - -/** - * https://github.com/electron/electron/blob/master/docs/api/dialog.md - * See `dialog.showOpenDialog()` - */ - -type electron$dialogOpenOptions = { - title?: string, - defaultPath?: string, - buttonLabel?: string, - filters?: Array, - properties?: Array, -}; - -/** - * https://github.com/electron/electron/blob/master/docs/api/dialog.md - * See `dialog.showSaveDialog()` - */ - -type electron$dialogSaveOptions = { - title?: string, - defaultPath?: string, - buttonLabel?: string, - filters?: Array, -}; - -/** - * https://github.com/electron/electron/blob/master/docs/api/dialog.md - * See `dialog.showMessageBox()` - */ - -type electron$dialogMessageBoxOptions = { - type?: string, - buttons?: Array, - defaultId?: number, - title?: string, - message?: string, - detail?: string, - icon?: electron$NativeImage, - cancelId?: number, - noLink?: boolean, -}; - -/** - * https://github.com/electron/electron/blob/master/docs/api/global-shortcut.md - */ - -type electron$globalShortcut = {}; - -/** - * https://github.com/electron/electron/blob/master/docs/api/ipc-main.md - */ - -declare class electron$IpcMain {} - -/** - * https://github.com/electron/electron/blob/master/docs/api/menu.md - */ - -declare class electron$Menu { - static setApplicationMenu(menu: electron$Menu): void, - static getApplicationMenu(): ?electron$Menu, - static sendActionToFirstResponder(action: string): void, - static buildFromTemplate(templates: Array): electron$Menu, - popup( - browserWindow: electron$BrowserWindow, - x?: number, - y?: number, - positioningItem?: number, - ): void, - popup(x?: number, y?: number, positioningItem?: number): void, - append(menuItem: electron$MenuItem): void, - insert(pos: number, menuItem: electron$MenuItem): void, - items: Array, -} - -/** - * https://github.com/electron/electron/blob/master/docs/api/menu-item.md - */ - -type electron$MenuItemOptions = { - click?: ( - menuItem: electron$MenuItem, - browserWindow: electron$BrowserWindow, - event: Object - ) => void, - role?: 'undo' | 'redo' | 'cut' | 'copy' | 'paste' | 'pasteandmatchstyle' | - 'selectall' | 'delete' | 'minimize' | 'close' | 'quit' | 'togglefullscreen' | - // macOS-only - 'about' | 'hide' | 'hideothers' | 'unhide' | 'front' | 'zoom' | 'window' | - 'help' | 'services', - type?: 'normal' | 'separator' | 'submenu' | 'checkbox' | 'radio', - label?: string, - sublabel?: string, - accelerator?: string, - icon?: electron$NativeImage, - enabled?: boolean, - visible?: boolean, - checked?: boolean, - submenu?: electron$MenuItem | electron$MenuItemOptions, - id?: string, - position?: string, -}; - -declare class electron$MenuItem { - constructor(options: electron$MenuItemOptions): void, - enabled: boolean, - visible: boolean, - checked: boolean, -} - -/** - * https://github.com/electron/electron/blob/master/docs/api/power-monitor.md - */ - -type electron$powerMonitor = {}; - -/** - * https://github.com/electron/electron/blob/master/docs/api/power-save-blocker.md - */ - -type electron$powerSaveBlocker = {}; - -/** - * https://github.com/electron/electron/blob/master/docs/api/protocol.md - */ - -type electron$protocol = {}; - -/** - * https://github.com/electron/electron/blob/master/docs/api/session.md - */ - -type electron$session = {}; - -/** - * https://github.com/electron/electron/blob/master/docs/api/system-preferences.md - */ - -type electron$systemPreferences = {}; - -/** - * https://github.com/electron/electron/blob/master/docs/api/tray.md - */ - -declare class electron$Tray {} - -/** - * https://github.com/electron/electron/blob/master/docs/api/web-contents.md - */ - -declare class electron$WebContents extends events$EventEmitter { - send(channel: string, ...args: Array): void, -} - -type electron$webContents = { - getAllWebContents(): Array, - getFocusedWebContents: ?electron$WebContents, -}; - -//------------------------------------------------------------------------------ -// Modules for the Renderer Process (Web Page) -//------------------------------------------------------------------------------ - -/** - * https://github.com/electron/electron/blob/master/docs/api/desktop-capturer.md - */ - -type electron$desktopCapturer = {}; - -/** - * https://github.com/electron/electron/blob/master/docs/api/ipc-renderer.md - */ - -declare class electron$IpcRenderer { - on(channel: string, callback: (...args: Array) => void): electron$IpcRenderer, - once(channel: string, callback: (...args: Array) => void): electron$IpcRenderer, - removeListener(channel: string, callback: (...args: Array) => void): electron$IpcRenderer, - removeAllListeners(channel?: string): electron$IpcRenderer, - send(channel: string, ...args: Array): void, - sendSync(channel: string, ...args: Array): void, - sendToHost(channel: string, ...args: Array): void, -} - -/** - * https://github.com/electron/electron/blob/master/docs/api/remote.md - */ - -type electron$remote = { - // main process built-in modules: - app: electron$app, - autoUpdater: electron$autoUpdater, - BrowserWindow: typeof electron$BrowserWindow, - contentTracing: electron$contentTracing, - dialog: electron$dialog, - globalShortcut: electron$globalShortcut, - ipcMain: electron$IpcMain, - Menu: typeof electron$Menu, - MenuItem: typeof electron$MenuItem, - powerMonitor: electron$powerMonitor, - powerSaveBlocker: electron$powerSaveBlocker, - protocol: electron$protocol, - session: electron$session, - electron$Tray: typeof electron$Tray, - webContents: electron$webContents, - // methods: - require(module: string): any, - getCurrentWindow(): electron$BrowserWindow, - getCurrentWebContents(): electron$WebContents, - getGlobal(name: string): ?mixed, - process: typeof process, -}; - -/** - * https://github.com/electron/electron/blob/master/docs/api/web-frame.md - */ - -type electron$webFrame = {}; - - -//------------------------------------------------------------------------------ -// Modules for Both Processes -//------------------------------------------------------------------------------ - -/** - * https://github.com/electron/electron/blob/master/docs/api/clipboard.md - */ - -type electron$clipboard = {}; - -/** - * https://github.com/electron/electron/blob/master/docs/api/crash-reporter.md - */ - -type electron$crashReporter = {}; - -/** - * https://github.com/electron/electron/blob/master/docs/api/native-image.md - */ - -type electron$nativeImage = { - createEmpty(): electron$NativeImage, - createFromPath(path: string): electron$NativeImage, - createFromBuffer(buffer: Buffer, scaleFactor?: number): electron$NativeImage, - createFromDataURL(dataURL: string): electron$NativeImage, -}; - -declare class electron$NativeImage { - toPNG(): Uint8Array, - toJPEG(quality: number): Uint8Array, - toBitmap(): Uint8Array, - toDataURL(): string, - getNativeHandle(): Uint8Array, - isEmpty(): boolean, - getSize(): {width: number, height: number}, - setTemplateImage(option: boolean): void, - isTemplateImage(): boolean, - // Deprecated, but Atom is behind - so keep them around. - toPng(): Uint8Array, - toJpeg(quality: number): Uint8Array, - toDataUrl(): string, -} - -/** - * https://github.com/electron/electron/blob/master/docs/api/screen.md - */ - -type electron$Display = { - id: number, - rotation: 0 | 90 | 180 | 270, - scaleFactor: number, - touchSupport: 'available' | 'unavailable' | 'unknown', - bounds: electron$rect, - size: {height: number, width: number}, - workArea: electron$rect, - workAreaSize: {height: number, width: number}, -}; - -type electron$DisplayEvents = - 'display-added' - | 'display-removed' - | 'display-metrics-changed'; - -type electron$ScreenListener = ( - event: electron$DisplayEvents, - callback: ( - event: Object, - display: electron$Display, - changedMetrics?: Array<'bounds' | 'workArea' | 'scaleFactor' | 'rotation'>, - ) => void, -) => electron$Screen; - -declare class electron$Screen { - on: electron$ScreenListener, - once: electron$ScreenListener, - removeAllListeners(event?: electron$DisplayEvents): electron$Screen, - removeListener(event?: electron$DisplayEvents, callback: Function): electron$Screen, - getCursorScreenPoint(): {x: number, y: number}, - getPrimaryDisplay(): electron$Display, - getAllDisplays(): Array, - getDisplayNearestPoint(point: {x: number, y: number}): electron$Display, - getDisplayMatching(rect: electron$rect): electron$Display, -} - -/** - * https://github.com/electron/electron/blob/master/docs/api/shell.md - */ - -type electron$shell = { - showItemInFolder(fullPath: string): void, - openItem(fullPath: string): void, - openExternal(url: string, options?: {activate: boolean}): void, - moveItemToTrash(fullPath: string): boolean, - beep(): void, - // Windows-only - writeShortcutLink( - shortcutPath: string, - operation?: 'create' | 'update' | 'replace', - options?: { - target: string, - cwd?: string, - args?: string, - description?: string, - icon?: string, - iconIndex?: number, - appUserModelId?: string, - } - ): void, - // Windows-only - readShortcutLink(shortcutPath: string): void, -}; diff --git a/flow-libs/event-kit.js.flow b/flow-libs/event-kit.js.flow deleted file mode 100644 index 769d91f89b..0000000000 --- a/flow-libs/event-kit.js.flow +++ /dev/null @@ -1,15 +0,0 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the license found in the LICENSE file in - * the root directory of this source tree. - * - * @flow - */ - -declare module 'event-kit' { - declare class Emitter extends atom$Emitter {} - declare class Disposable extends atom$Disposable {} - declare class CompositeDisposable extends atom$CompositeDisposable {} -} diff --git a/flow-libs/jasmine.js.flow b/flow-libs/jasmine.js.flow deleted file mode 100644 index 3482cf5007..0000000000 --- a/flow-libs/jasmine.js.flow +++ /dev/null @@ -1,138 +0,0 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the license found in the LICENSE file in - * the root directory of this source tree. - * - * @flow - */ - -// Type declarations for Jasmine v1.3 -// https://jasmine.github.io/1.3/introduction.html - -type JasmineMatcher = { - not: JasmineMatcher, - toBe(expected: mixed): boolean, - toContain(item: mixed): boolean, - toBeCloseTo(expected: number, precision: number): boolean, - toBeDefined(): boolean, - toBeFalsy(): boolean, - toBeTruthy(): boolean, - toBeGreaterThan(expected: number): boolean, - toBeLessThan(expected: number): boolean, - toBeNull(): boolean, - toBeUndefined(): boolean, - toEqual(expected: mixed): boolean, - toExist(): boolean, - toHaveBeenCalled(): boolean, - toHaveBeenCalledWith(...args: Array): boolean, - toMatch(expected: mixed): boolean, - toMatchSelector(expected: string): boolean, - toThrow(): boolean, - - // Custom Matchers from nuclide-test-helpers - diffJson(expected: mixed): boolean, - diffLines(expected: string): boolean, - - // Custom Matchers from nuclide-atom-test-helpers - toEqualAtomRange(): boolean, - toEqualAtomRanges(): boolean, -}; - -// Declaring, describing, and grouping tests -declare function afterEach(func: () => mixed): void; -declare function beforeEach(func: () => mixed): void; -declare function describe(title: string, spec: () => mixed): void; -declare function expect(actual: mixed): JasmineMatcher; -declare function it(title: string, spec: () => mixed): void; - -// Disabling Specs and Suites -// https://jasmine.github.io/1.3/introduction.html#section-Disabling_Specs_and_Suites -declare function xdescribe(title: string, spec: () => mixed): void; -declare function xit(title: string, spec: () => mixed): void; - -// Spies -// https://jasmine.github.io/1.3/introduction.html#section-Spies -type JasmineSpyCall = { - args: Array, -}; - -type JasmineSpy = { - (...args: Array): any, - andCallFake(fake: (...args: Array) => mixed): JasmineSpy, - andCallThrough(): JasmineSpy, - argsForCall: Array>, - andReturn(value: T): JasmineSpy, - andThrow(error: mixed): JasmineSpy, - callCount: number, - calls: Array, - identity: string, - mostRecentCall: JasmineSpyCall, - wasCalled: boolean, - reset(): void, -}; - -declare function spyOn(object: Object, method: string): JasmineSpy; - -// Mocking the JavaScript Clock -// https://jasmine.github.io/1.3/introduction.html#section-Mocking_the_JavaScript_Clock -type JasmineMockClock = { - tick(milliseconds: number): void, - useMock(): void, -}; - -// Asynchronous Support -// https://jasmine.github.io/1.3/introduction.html#section-Asynchronous_Support -declare function runs(func: () => mixed): void; - -// Apparently the arguments for waitsFor() can be specified in any order. -type WaitsForArg = string | number | () => mixed; - -declare function waitsFor( - latchFunction?: WaitsForArg, failureMessage?: WaitsForArg, timeout?: WaitsForArg): void; - -declare function waits(milliseconds: number): void; - -type JasmineEnvironment = { - currentSpec: { - fail(message: string): void, - }, - defaultTimeoutInterval: number, - afterEach: afterEach, - beforeEach: beforeEach, - describe: describe, - it: it, -}; - -type JasmineSpec = { - addMatchers(matchersPrototype: {[methodName: string]: (expected: any) => boolean}): void, -}; - -type JasmineMatchers = { - message: () => string, -}; - -// Jasmine global -declare var jasmine: { - // Default timeout. - DEFAULT_TIMEOUT_INTERVAL: number, - - Clock: JasmineMockClock, - Matchers: JasmineMatchers, - any(expected: string | Object): mixed, - - /** - * This is a non-standard method that Atom adds to Jasmine via spec-helper.coffee. - * Ideally, we would declare this in atom-jasmine.js, but we can't extend this global here. - */ - attachToDOM(element: Element): ?HTMLElement, - - createSpy: (name?: string) => JasmineSpy, - createSpyObj: (name: string, spyNames: Array) => {[key: string]: JasmineSpy}, - getEnv: () => JasmineEnvironment, - pp: (value: mixed) => string, - unspy: (obj: Object, methodName: string) => void, - useMockClock: () => void, - useRealClock: () => void, -}; diff --git a/flow-libs/need-to-upstream-to-flow-lib.js.flow b/flow-libs/need-to-upstream-to-flow-lib.js.flow deleted file mode 100644 index 16e86d6887..0000000000 --- a/flow-libs/need-to-upstream-to-flow-lib.js.flow +++ /dev/null @@ -1,127 +0,0 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the license found in the LICENSE file in - * the root directory of this source tree. - * - * @flow - */ - -/* - * APIs listed in this file are ones that should be built into Flow and need to be upstreamed. - */ - -type IDisposable = { - dispose(): mixed, -}; - -/* - * These Notification & NotificationOptions definitions are not exhaustive while standardization, - * browser, and Electron support remain incomplete. - */ -type NotificationOptions = { - body?: string, - icon?: string, -}; - -declare class Notification { - constructor( - message: string, - options?: NotificationOptions, - ): void, -} - -// T9254051 - Fix flow http/https definitions. -declare class http$fixed$Server extends events$EventEmitter { - listen(port: number, hostname?: string, backlog?: number, callback?: Function): http$fixed$Server, - listen(path: string, callback?: Function): http$fixed$Server, - listen(handle: Object, callback?: Function): http$fixed$Server, - close(callback?: Function): http$fixed$Server, - address(): {port: number, fmaily: string, address: string}, - maxHeadersCount: number, -} - -declare class http$fixed$IncomingMessage extends stream$Readable { - headers: Object, - httpVersion: string, - method: string, - trailers: Object, - setTimeout(msecs: number, callback: Function): void, - socket: any, // TODO net.Socket - statusCode: number, - url: string, - connection: { destroy: () => void }, -} - -declare class http$fixed$ClientRequest extends stream$Writable { -} - -declare class http$fixed$ServerResponse { - setHeader(name: string, value: string): void, - statusCode: number, - write(value: string): void, - end(): void, -} - -declare class https$fixed { - Server: typeof http$fixed$Server, - createServer( - options: Object, - requestListener?: ( - request: http$fixed$IncomingMessage, - response: http$fixed$ServerResponse, - ) => void, - ): http$fixed$Server, - request( - options: Object | string, - callback: (response: http$fixed$IncomingMessage) => void - ): http$fixed$ClientRequest, - get( - options: Object | string, - callback: (response: http$fixed$IncomingMessage) => void - ): http$fixed$ClientRequest, -} - -declare class http$fixed { - Server: typeof http$fixed$Server, - createServer( - requestListener?: ( - request: http$fixed$IncomingMessage, - response: http$fixed$ServerResponse, - ) => void - ): http$fixed$Server, - request( - options: Object | string, - callback: (response: http$fixed$IncomingMessage) => void - ): http$fixed$ClientRequest, - get( - options: Object | string, - callback: (response: http$fixed$IncomingMessage) => void - ): http$fixed$ClientRequest, -} - -declare class module$Module { - constructor( - id?: string, - parent?: string | module$Module - ): void, - id: ?string, - exports: any, - parent?: string | module$Module, - filename?: string, - loaded: boolean, - children: Array, - paths: Array, - _compile: (content: string, filename: string) => void, - - static _resolveFilename(filename: string, module: any): string, -} - -declare module 'module' { - declare var exports: typeof module$Module; -} - -declare module 'console' { - declare var exports: any; -} diff --git a/flow-libs/simple-text-buffer.js.flow b/flow-libs/simple-text-buffer.js.flow deleted file mode 100644 index 7cc09d460b..0000000000 --- a/flow-libs/simple-text-buffer.js.flow +++ /dev/null @@ -1,105 +0,0 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the license found in the LICENSE file in - * the root directory of this source tree. - * - * @flow - */ - -declare class simpleTextBuffer$TextBuffer { - constructor(contents: string): void, - - // Mixin - static deserialize: (state: Object, params: Object) => mixed, - - // Events - onWillChange(callback: (event: atom$TextEditEvent) => mixed): IDisposable, - onDidChange(callback: (event: atom$TextEditEvent) => mixed): IDisposable, - onDidStopChanging(callback: () => mixed): IDisposable, - onDidChangeModified(callback: () => mixed): IDisposable, - onDidChangeEncoding(callback: () => mixed): IDisposable, - onDidDestroy(callback: () => mixed): IDisposable, - - // File Details - setEncoding(encoding: string): void, - getEncoding(): string, - getId(): string, - - // Reading Text - isEmpty(): boolean, - getText(): string, - getTextInRange(range: atom$RangeLike): string, - getLineCount(): number, - getLines(): Array, - getLastLine(): string, - lineForRow(row: number): string, - lineEndingForRow(row: number): string, - lineLengthForRow(row: number): number, - isRowBlank(row: number): boolean, - previousNonBlankRow(startRow: number): ?number, - nextNonBlankRow(startRow: number): ?number, - - // Mutating Text - setText(text: string): atom$Range, - setTextInRange( - range: atom$RangeLike, text: string, options?: Object): atom$Range, - setTextViaDiff(text: string): void, - insert( - position: atom$Point, - text: string, - options?: { - normalizeLineEndings?: boolean, - undo?: string, - }, - ): atom$Range, - append(text: string, options: ?{ - normalizeLineEndings?: boolean, - undo?: string, - }): atom$Range, - delete(range: atom$Range): atom$Range, - deleteRows(startRow: number, endRow: number): atom$Range, - - // History - undo(): void, - redo(): void, - transact(fn: () => mixed, _: void): void, - transact(groupingInterval: number, fn: () => mixed): void, - clearUndoStack(): void, - createCheckpoint(): atom$TextBufferCheckpoint, - revertToCheckpoint(checkpoint: atom$TextBufferCheckpoint): boolean, - groupChangesSinceCheckpoint(checkpoint: atom$TextBufferCheckpoint): boolean, - // TODO describe the return type more precisely. - getChangesSinceCheckpoint(checkpoint: atom$TextBufferCheckpoint): Array, - - // Search And Replace - scanInRange(regex: RegExp, range: atom$Range, iterator: TextBufferScanIterator): void, - backwardsScanInRange( - regex: RegExp, range: atom$Range, iterator: TextBufferScanIterator): void, - - // Buffer Range Details - getLastRow(): number, - getRange(): atom$Range, - rangeForRow(row: number, includeNewLine?: boolean): atom$Range, - - // Position/Index mapping - characterIndexForPosition(position: atom$PointLike): number, - positionForCharacterIndex(index: number): atom$Point, - - // Private APIs - emitter: atom$Emitter, - refcount: number, - changeCount: number, - destroy(): void, - isDestroyed(): boolean, - - static Point: typeof atom$Point, - static Range: typeof atom$Range, -} - -declare module 'simple-text-buffer' { - declare export var Point: typeof atom$Point; - declare export var Range: typeof atom$Range; - declare export default typeof simpleTextBuffer$TextBuffer; -} diff --git a/flow-libs/uuid.js.flow b/flow-libs/uuid.js.flow deleted file mode 100644 index 968d8ce83f..0000000000 --- a/flow-libs/uuid.js.flow +++ /dev/null @@ -1,19 +0,0 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the license found in the LICENSE file in - * the root directory of this source tree. - * - * @flow - */ - -/** - * The `uuid` generates RFC-compliant UUIDs in JavaScript. It has a more - * extensive API than the one defined here, but this all we use from it. - * - * {@link https://github.com/broofa/node-uuid} - */ -declare module 'uuid' { - declare function v4(): string; -} diff --git a/flow-libs/ws.js.flow b/flow-libs/ws.js.flow deleted file mode 100644 index 6a26b51016..0000000000 --- a/flow-libs/ws.js.flow +++ /dev/null @@ -1,41 +0,0 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the license found in the LICENSE file in - * the root directory of this source tree. - * - * @flow - */ - -/** - * https://github.com/websockets/ws/blob/master/doc/ws.md - */ - -declare module 'ws' { - declare class ws$Server extends events$EventEmitter { - // TODO properly type the options object - constructor(options: Object): void, - close(): void, - } - - declare class ws$WebSocket extends events$EventEmitter { - static Server: typeof ws$Server, - - onopen?: () => mixed, - onclose?: () => mixed, - onerror?: () => mixed, - - send(message: string | Buffer, ack?: (error: ?Object) => void): void, - send(message: string | Buffer, options: Object, ack: (error: ?Object) => void): void, - close(): void, - terminate(): void, - ping( - data: ?string, - options?: {mask?: boolean, binary?: boolean}, - dontFailWhenClosed?: boolean, - ): void, - } - - declare var exports: typeof ws$WebSocket; -} diff --git a/flow-typed/README.md b/flow-typed/README.md deleted file mode 100644 index 66f90f9a56..0000000000 --- a/flow-typed/README.md +++ /dev/null @@ -1,14 +0,0 @@ -## flow-typed - -The definitions under the `npm` folder here are pulled down from -[`flow-typed`](https://github.com/flowtype/flow-typed). Please do not change these files directly. - -### Updating these definitions - -1. Put up a pull request on [`flow-typed`](https://github.com/flowtype/flow-typed) with the proposed changes. Include tests. -2. Once it's merged, update the files here by either bothering @nmote, or - - `npm install -g flow-typed` (as of this writing, it's in beta so you will need to install `flow-typed@2.0.0-beta4` to get the CLI). - - `flow-typed install packageName -f flowVersion -o`, where: - - `packageName` is the name of the package (e.g. `classnames` or `rxjs`) - - `flowVersion` is the Flow version we are currently using e.g. `0.25.0` - - `-o` just indicates the the existing defs should be overwritten diff --git a/flow-typed/npm/classnames_v2.x.x.js b/flow-typed/npm/classnames_v2.x.x.js deleted file mode 100644 index 675f2a76a6..0000000000 --- a/flow-typed/npm/classnames_v2.x.x.js +++ /dev/null @@ -1,15 +0,0 @@ -// flow-typed signature: 62bc5615b7c27f8f00718fec93336e7f -// flow-typed version: ef0148e929/classnames_v2.x.x/flow_>=v0.28.x - -type $npm$classnames$Classes = - string | - {[className: string]: ?boolean } | - Array | - void | - null - -declare module 'classnames' { - declare function exports( - ...classes: Array<$npm$classnames$Classes> - ): string; -} diff --git a/flow-typed/npm/lru-cache_v4.0.x.js b/flow-typed/npm/lru-cache_v4.0.x.js deleted file mode 100644 index 0c9560c014..0000000000 --- a/flow-typed/npm/lru-cache_v4.0.x.js +++ /dev/null @@ -1,26 +0,0 @@ -// flow-typed signature: bb8c907e5137ea7b164eca6cb4839acc -// flow-typed version: a9bec9eec1/lru-cache_v4.0.x/flow_>=v0.26.0 - -declare module 'lru-cache' { - - declare type LRUCache = { - set: (key: K, value: V, maxAge?: number) => void; - get: (key: K) => V; - peek: (key: K) => V; - del: (key: K) => void; - reset: () => void; - has: (key: K) => boolean; - // TODO add the rest of the things documented at https://www.npmjs.com/package/lru-cache - }; - - declare type Options = { - max?: number; - maxAge?: number; - length?: (value: V, key: K) => number; - dispose?: (key: K, value: V) => void; - stale?: boolean; - }; - - // TODO You can supply just an integer (max size), or even nothing at all. - declare var exports: (options: Options) => LRUCache; -} diff --git a/flow-typed/npm/rxjs_v5.0.x.js b/flow-typed/npm/rxjs_v5.0.x.js deleted file mode 100644 index 05b9c7e1e3..0000000000 --- a/flow-typed/npm/rxjs_v5.0.x.js +++ /dev/null @@ -1,740 +0,0 @@ -// flow-typed signature: 677aa2f2bb526291b874fc69ff0fae00 -// flow-typed version: 6194e56223/rxjs_v5.0.x/flow_>=v0.34.x - -// FIXME(samgoldman) Remove top-level interface once Babel supports -// `declare interface` syntax. -// FIXME(samgoldman) Remove this once rxjs$Subject can mixin rxjs$Observer -interface rxjs$IObserver<-T> { - next(value: T): mixed; - error(error: any): mixed; - complete(): mixed; -} - -type rxjs$PartialObserver<-T> = - | { - +next: (value: T) => mixed; - +error?: (error: any) => mixed; - +complete?: () => mixed; - } - | { - +next?: (value: T) => mixed; - +error: (error: any) => mixed; - +complete?: () => mixed; - } - | { - +next?: (value: T) => mixed; - +error?: (error: any) => mixed; - +complete: () => mixed; - } - -interface rxjs$ISubscription { - unsubscribe(): void; -} - -type rxjs$TeardownLogic = rxjs$ISubscription | () => void; - -type rxjs$EventListenerOptions = { - capture?: boolean; - passive?: boolean; - once?: boolean; -} | boolean; - -declare class rxjs$Observable<+T> { - static concat(...sources: rxjs$Observable[]): rxjs$Observable; - - static create( - subscribe: (observer: rxjs$Observer) => rxjs$ISubscription | Function | void - ): rxjs$Observable; - - static defer(observableFactory: () => rxjs$Observable | Promise): rxjs$Observable; - - static from(iterable: Iterable): rxjs$Observable; - - static fromEvent(element: any, eventName: string, ...none: Array): rxjs$Observable; - static fromEvent( - element: any, - eventName: string, - options: rxjs$EventListenerOptions, - ...none: Array - ): rxjs$Observable; - static fromEvent( - element: any, - eventName: string, - selector: () => T, - ...none: Array - ): rxjs$Observable; - static fromEvent( - element: any, - eventName: string, - options: rxjs$EventListenerOptions, - selector: () => T, - ): rxjs$Observable; - - static fromEventPattern( - addHandler: (handler: () => void) => void, - removeHandler: (handler: () => void) => void, - selector?: () => T, - ): rxjs$Observable; - - static fromPromise(promise: Promise): rxjs$Observable; - - static empty(): rxjs$Observable; - - static interval(period: number): rxjs$Observable; - - static merge( - source0: rxjs$Observable, - source1: rxjs$Observable, - ): rxjs$Observable; - static merge( - source0: rxjs$Observable, - source1: rxjs$Observable, - source2: rxjs$Observable, - ): rxjs$Observable; - static merge(...sources: rxjs$Observable[]): rxjs$Observable; - - static never(): rxjs$Observable; - - static of(...values: T[]): rxjs$Observable; - - static throw(error: any): rxjs$Observable; - - audit(durationSelector: (value: T) => rxjs$Observable | Promise): rxjs$Observable; - - race(other: rxjs$Observable): rxjs$Observable; - - buffer(bufferBoundaries: rxjs$Observable): rxjs$Observable>; - - catch(selector: (err: any, caught: rxjs$Observable) => rxjs$Observable): rxjs$Observable; - - concat(...sources: rxjs$Observable[]): rxjs$Observable; - - concatAll(): rxjs$Observable; - - concatMap( - f: (value: T) => rxjs$Observable | Promise | Iterable - ): rxjs$Observable; - - debounceTime(duration: number): rxjs$Observable; - - delay(dueTime: number): rxjs$Observable; - - distinctUntilChanged(compare?: (x: T, y: T) => boolean): rxjs$Observable; - - distinct(keySelector?: (value: T) => U, flushes?: rxjs$Observable): rxjs$Observable; - - distinctUntilKeyChanged(key: string, compare?: (x: mixed, y: mixed) => boolean): rxjs$Observable; - - elementAt(index: number, defaultValue?: T): rxjs$Observable; - - filter(predicate: (value: T) => boolean): rxjs$Observable; - - finally(f: () => mixed): rxjs$Observable; - - first( - predicate?: (value: T, index: number, source: rxjs$Observable) => boolean, - ): rxjs$Observable; - first( - predicate: ?(value: T, index: number, source: rxjs$Observable) => boolean, - resultSelector: (value: T, index: number) => U, - ): rxjs$Observable; - first( - predicate: ?(value: T, index: number, source: rxjs$Observable) => boolean, - resultSelector: ?(value: T, index: number) => U, - defaultValue: U, - ): rxjs$Observable; - - groupBy( - keySelector: (value: T) => mixed, - elementSelector?: (value: T) => T, - compare?: (x: T, y: T) => boolean, - ): rxjs$Observable>; - - ignoreElements(): rxjs$Observable; - - let(project: (self: rxjs$Observable) => rxjs$Observable): rxjs$Observable; - - // Alias for `let` - letBind(project: (self: rxjs$Observable) => rxjs$Observable): rxjs$Observable; - - switch(): T; // assumption: T is Observable - - // Alias for `mergeMap` - flatMap( - project: (value: T) => rxjs$Observable | Promise | Iterable - ): rxjs$Observable; - - switchMap( - project: (value: T) => rxjs$Observable | Promise | Iterable - ): rxjs$Observable; - - switchMapTo( - innerObservable: rxjs$Observable, - ): rxjs$Observable; - - map(f: (value: T) => U): rxjs$Observable; - - mapTo(value: U): rxjs$Observable; - - merge(other: rxjs$Observable): rxjs$Observable; - - mergeAll(): rxjs$Observable; - - mergeMap( - project: (value: T, index?: number) => rxjs$Observable | Promise | Iterable, - ): rxjs$Observable; - - multicast( - subjectOrSubjectFactory: rxjs$Subject | () => rxjs$Subject, - ): rxjs$ConnectableObservable; - - observeOn(scheduler: rxjs$SchedulerClass): rxjs$Observable; - - pairwise(): rxjs$Observable<[T, T]>; - - publish(): rxjs$ConnectableObservable; - - publishLast(): rxjs$ConnectableObservable; - - reduce( - accumulator: ( - acc: U, - currentValue: T, - index: number, - source: rxjs$Observable, - ) => U, - seed: U, - ): rxjs$Observable; - - sample(notifier: rxjs$Observable): rxjs$Observable; - - sampleTime(delay: number): rxjs$Observable; - - publishReplay(): rxjs$ConnectableObservable; - - retry(retryCount: number): rxjs$Observable; - - retryWhen(notifier: (errors: rxjs$Observable) => rxjs$Observable): rxjs$Observable; - - scan( - f: (acc: U, value: T) => U, - initialValue: U, - ): rxjs$Observable; - - share(): rxjs$Observable; - - skip(count: number): rxjs$Observable; - - skipUntil(other: rxjs$Observable | Promise): rxjs$Observable; - - skipWhile(predicate: (value: T) => boolean): rxjs$Observable; - - startWith(...values: Array): rxjs$Observable; - - subscribeOn(scheduler: rxjs$SchedulerClass): rxjs$Observable; - - take(count: number): rxjs$Observable; - - takeUntil(other: rxjs$Observable): rxjs$Observable; - - takeWhile(f: (value: T) => boolean): rxjs$Observable; - - do( - onNext?: (value: T) => mixed, - onError?: (error: any) => mixed, - onCompleted?: () => mixed, - ): rxjs$Observable; - do(observer: { - next?: (value: T) => mixed; - error?: (error: any) => mixed; - complete?: () => mixed; - }): rxjs$Observable; - - throttleTime(duration: number): rxjs$Observable; - - timeout(due: number | Date, _: void): rxjs$Observable; - - toArray(): rxjs$Observable; - - toPromise(): Promise; - - subscribe(observer: rxjs$PartialObserver): rxjs$Subscription; - subscribe( - onNext: ?(value: T) => mixed, - onError: ?(error: any) => mixed, - onCompleted: ?() => mixed, - ): rxjs$Subscription; - - static combineLatest( - a: rxjs$Observable, - resultSelector: (a: A) => B, - ): rxjs$Observable; - - static combineLatest( - a: rxjs$Observable, - b: rxjs$Observable, - resultSelector: (a: A, b: B) => C, - ): rxjs$Observable; - - static combineLatest( - a: rxjs$Observable, - b: rxjs$Observable, - c: rxjs$Observable, - resultSelector: (a: A, b: B, c: C) => D, - ): rxjs$Observable; - - static combineLatest( - a: rxjs$Observable, - b: rxjs$Observable, - c: rxjs$Observable, - d: rxjs$Observable, - resultSelector: (a: A, b: B, c: C, d: D) => E, - ): rxjs$Observable; - - static combineLatest( - a: rxjs$Observable, - b: rxjs$Observable, - c: rxjs$Observable, - d: rxjs$Observable, - e: rxjs$Observable, - resultSelector: (a: A, b: B, c: C, d: D, e: E) => F, - ): rxjs$Observable; - - static combineLatest( - a: rxjs$Observable, - b: rxjs$Observable, - c: rxjs$Observable, - d: rxjs$Observable, - e: rxjs$Observable, - f: rxjs$Observable, - resultSelector: (a: A, b: B, c: C, d: D, e: E, f: F) => G, - ): rxjs$Observable; - - static combineLatest( - a: rxjs$Observable, - b: rxjs$Observable, - c: rxjs$Observable, - d: rxjs$Observable, - e: rxjs$Observable, - f: rxjs$Observable, - g: rxjs$Observable, - resultSelector: (a: A, b: B, c: C, d: D, e: E, f: F, g: G) => H, - ): rxjs$Observable; - - static combineLatest( - a: rxjs$Observable, - b: rxjs$Observable, - _: void, - ): rxjs$Observable<[A, B]>; - - static combineLatest( - a: rxjs$Observable, - b: rxjs$Observable, - c: rxjs$Observable, - _: void, - ): rxjs$Observable<[A, B, C]>; - - static combineLatest( - a: rxjs$Observable, - b: rxjs$Observable, - c: rxjs$Observable, - d: rxjs$Observable, - _: void, - ): rxjs$Observable<[A, B, C, D]>; - - static combineLatest( - a: rxjs$Observable, - b: rxjs$Observable, - c: rxjs$Observable, - d: rxjs$Observable, - e: rxjs$Observable, - _: void, - ): rxjs$Observable<[A, B, C, D, E]>; - - static combineLatest( - a: rxjs$Observable, - b: rxjs$Observable, - c: rxjs$Observable, - d: rxjs$Observable, - e: rxjs$Observable, - f: rxjs$Observable, - _: void, - ): rxjs$Observable<[A, B, C, D, E, F]>; - - static combineLatest( - a: rxjs$Observable, - b: rxjs$Observable, - c: rxjs$Observable, - d: rxjs$Observable, - e: rxjs$Observable, - f: rxjs$Observable, - g: rxjs$Observable, - _: void, - ): rxjs$Observable<[A, B, C, D, E, F, G]>; - - static combineLatest( - a: rxjs$Observable, - b: rxjs$Observable, - c: rxjs$Observable, - d: rxjs$Observable, - e: rxjs$Observable, - f: rxjs$Observable, - g: rxjs$Observable, - h: rxjs$Observable, - _: void, - ): rxjs$Observable<[A, B, C, D, E, F, G, H]>; - - combineLatest( - a: rxjs$Observable, - _: void, - ): rxjs$Observable<[T, A]>; - - combineLatest( - a: rxjs$Observable, - resultSelector: (a: A) => B, - ): rxjs$Observable; - - combineLatest( - a: rxjs$Observable, - b: rxjs$Observable, - resultSelector: (a: A, b: B) => C, - ): rxjs$Observable; - - combineLatest( - a: rxjs$Observable, - b: rxjs$Observable, - c: rxjs$Observable, - resultSelector: (a: A, b: B, c: C) => D, - ): rxjs$Observable; - - combineLatest( - a: rxjs$Observable, - b: rxjs$Observable, - c: rxjs$Observable, - d: rxjs$Observable, - resultSelector: (a: A, b: B, c: C, d: D) => E, - ): rxjs$Observable; - - combineLatest( - a: rxjs$Observable, - b: rxjs$Observable, - c: rxjs$Observable, - d: rxjs$Observable, - e: rxjs$Observable, - resultSelector: (a: A, b: B, c: C, d: D, e: E) => F, - ): rxjs$Observable; - - combineLatest( - a: rxjs$Observable, - b: rxjs$Observable, - c: rxjs$Observable, - d: rxjs$Observable, - e: rxjs$Observable, - f: rxjs$Observable, - resultSelector: (a: A, b: B, c: C, d: D, e: E, f: F) => G, - ): rxjs$Observable; - - combineLatest( - a: rxjs$Observable, - b: rxjs$Observable, - c: rxjs$Observable, - d: rxjs$Observable, - e: rxjs$Observable, - f: rxjs$Observable, - g: rxjs$Observable, - resultSelector: (a: A, b: B, c: C, d: D, e: E, f: F, g: G) => H, - ): rxjs$Observable; - - static forkJoin( - a: rxjs$Observable, - resultSelector: (a: A) => B, - ): rxjs$Observable; - - static forkJoin( - a: rxjs$Observable, - b: rxjs$Observable, - resultSelector: (a: A, b: B) => C, - ): rxjs$Observable; - - static forkJoin( - a: rxjs$Observable, - b: rxjs$Observable, - c: rxjs$Observable, - resultSelector: (a: A, b: B, c: C) => D, - ): rxjs$Observable; - - static forkJoin( - a: rxjs$Observable, - b: rxjs$Observable, - c: rxjs$Observable, - d: rxjs$Observable, - resultSelector: (a: A, b: B, c: C, d: D) => E, - ): rxjs$Observable; - - static forkJoin( - a: rxjs$Observable, - b: rxjs$Observable, - c: rxjs$Observable, - d: rxjs$Observable, - e: rxjs$Observable, - resultSelector: (a: A, b: B, c: C, d: D, e: E) => F, - ): rxjs$Observable; - - static forkJoin( - a: rxjs$Observable, - b: rxjs$Observable, - c: rxjs$Observable, - d: rxjs$Observable, - e: rxjs$Observable, - f: rxjs$Observable, - resultSelector: (a: A, b: B, c: C, d: D, e: E, f: F) => G, - ): rxjs$Observable; - - static forkJoin( - a: rxjs$Observable, - b: rxjs$Observable, - c: rxjs$Observable, - d: rxjs$Observable, - e: rxjs$Observable, - f: rxjs$Observable, - g: rxjs$Observable, - resultSelector: (a: A, b: B, c: C, d: D, e: E, f: F, g: G) => H, - ): rxjs$Observable; - - static forkJoin( - a: rxjs$Observable, - b: rxjs$Observable, - _: void, - ): rxjs$Observable<[A, B]>; - - static forkJoin( - a: rxjs$Observable, - b: rxjs$Observable, - c: rxjs$Observable, - _: void, - ): rxjs$Observable<[A, B, C]>; - - static forkJoin( - a: rxjs$Observable, - b: rxjs$Observable, - c: rxjs$Observable, - d: rxjs$Observable, - _: void, - ): rxjs$Observable<[A, B, C, D]>; - - static forkJoin( - a: rxjs$Observable, - b: rxjs$Observable, - c: rxjs$Observable, - d: rxjs$Observable, - e: rxjs$Observable, - _: void, - ): rxjs$Observable<[A, B, C, D, E]>; - - static forkJoin( - a: rxjs$Observable, - b: rxjs$Observable, - c: rxjs$Observable, - d: rxjs$Observable, - e: rxjs$Observable, - f: rxjs$Observable, - _: void, - ): rxjs$Observable<[A, B, C, D, E, F]>; - - static forkJoin( - a: rxjs$Observable, - b: rxjs$Observable, - c: rxjs$Observable, - d: rxjs$Observable, - e: rxjs$Observable, - f: rxjs$Observable, - g: rxjs$Observable, - _: void, - ): rxjs$Observable<[A, B, C, D, E, F, G]>; - - static forkJoin( - a: rxjs$Observable, - b: rxjs$Observable, - c: rxjs$Observable, - d: rxjs$Observable, - e: rxjs$Observable, - f: rxjs$Observable, - g: rxjs$Observable, - h: rxjs$Observable, - _: void, - ): rxjs$Observable<[A, B, C, D, E, F, G, H]>; - - withLatestFrom( - a: rxjs$Observable, - _: void, - ): rxjs$Observable<[T, A]>; - - withLatestFrom( - a: rxjs$Observable, - resultSelector: (a: A) => B, - ): rxjs$Observable; - - withLatestFrom( - a: rxjs$Observable, - b: rxjs$Observable, - resultSelector: (a: A, b: B) => C, - ): rxjs$Observable; - - withLatestFrom( - a: rxjs$Observable, - b: rxjs$Observable, - c: rxjs$Observable, - resultSelector: (a: A, b: B, c: C) => D, - ): rxjs$Observable; - - withLatestFrom( - a: rxjs$Observable, - b: rxjs$Observable, - c: rxjs$Observable, - d: rxjs$Observable, - resultSelector: (a: A, b: B, c: C, d: D) => E, - ): rxjs$Observable; - - withLatestFrom( - a: rxjs$Observable, - b: rxjs$Observable, - c: rxjs$Observable, - d: rxjs$Observable, - e: rxjs$Observable, - resultSelector: (a: A, b: B, c: C, d: D, e: E) => F, - ): rxjs$Observable; - - withLatestFrom( - a: rxjs$Observable, - b: rxjs$Observable, - c: rxjs$Observable, - d: rxjs$Observable, - e: rxjs$Observable, - f: rxjs$Observable, - resultSelector: (a: A, b: B, c: C, d: D, e: E, f: F) => G, - ): rxjs$Observable; - - withLatestFrom( - a: rxjs$Observable, - b: rxjs$Observable, - c: rxjs$Observable, - d: rxjs$Observable, - e: rxjs$Observable, - f: rxjs$Observable, - g: rxjs$Observable, - resultSelector: (a: A, b: B, c: C, d: D, e: E, f: F, g: G) => H, - ): rxjs$Observable; - - static using( - resourceFactory: () => ?R, - observableFactory: (resource: R) => rxjs$Observable | Promise | void, - ): rxjs$Observable; -} - -declare class rxjs$ConnectableObservable extends rxjs$Observable { - connect(): rxjs$Subscription; - refCount(): rxjs$Observable; -} - -declare class rxjs$Observer { - next(value: T): mixed; - - error(error: any): mixed; - - complete(): mixed; -} - -// FIXME(samgoldman) should be `mixins rxjs$Observable, rxjs$Observer` -// once Babel parsing support exists: https://phabricator.babeljs.io/T6821 -declare class rxjs$Subject extends rxjs$Observable { - asObservable(): rxjs$Observable; - - observers: Array>; - - unsubscribe(): void; - - // Copied from rxjs$Observer - next(value: T): mixed; - error(error: any): mixed; - complete(): mixed; - - // For use in subclasses only: - _next(value: T): void; - _subscribe(observer: rxjs$PartialObserver): rxjs$Subscription; -} - -declare class rxjs$BehaviorSubject extends rxjs$Subject { - constructor(initialValue: T): void; - - getValue(): T; -} - -declare class rxjs$ReplaySubject extends rxjs$Subject { - -} - -declare class rxjs$Subscription { - unsubscribe(): void; - add(teardown: rxjs$TeardownLogic): rxjs$Subscription; -} - -declare class rxjs$SchedulerClass { - schedule(work: (state?: T) => void, delay?: number, state?: T): rxjs$Subscription; -} - -declare class rxjs$TimeoutError extends Error { -} - -declare module 'rxjs' { - declare module.exports: { - Observable: typeof rxjs$Observable, - ConnectableObservable: typeof rxjs$ConnectableObservable, - Subject: typeof rxjs$Subject, - BehaviorSubject: typeof rxjs$BehaviorSubject, - ReplaySubject: typeof rxjs$ReplaySubject, - Scheduler: { - asap: rxjs$SchedulerClass, - queue: rxjs$SchedulerClass, - animationFrame: rxjs$SchedulerClass, - async: rxjs$SchedulerClass, - }, - Subscription: typeof rxjs$Subscription, - TimeoutError: typeof rxjs$TimeoutError, - } -} - -declare module 'rxjs/Observable' { - declare module.exports: { - Observable: typeof rxjs$Observable - } -} - -declare module 'rxjs/Observer' { - declare module.exports: { - Observer: typeof rxjs$Observer - } -} - -declare module 'rxjs/BehaviorSubject' { - declare module.exports: { - BehaviorSubject: typeof rxjs$BehaviorSubject - } -} - -declare module 'rxjs/ReplaySubject' { - declare module.exports: { - ReplaySubject: typeof rxjs$ReplaySubject - } -} - -declare module 'rxjs/Subject' { - declare module.exports: { - Subject: typeof rxjs$Subject - } -} - -declare module 'rxjs/Subscription' { - declare module.exports: { - Subscription: typeof rxjs$Subscription - } -} diff --git a/flow-typed/npm/semver_v5.1.x.js b/flow-typed/npm/semver_v5.1.x.js deleted file mode 100644 index 18a9e66996..0000000000 --- a/flow-typed/npm/semver_v5.1.x.js +++ /dev/null @@ -1,71 +0,0 @@ -// flow-typed signature: 01cf1486a106f482123a7c6fefcd6424 -// flow-typed version: 1cae4101a9/semver_v5.1.x/flow_>=v0.27.0 - -// List of members taken from here: https://www.npmjs.com/package/semver/#functions -// TODO support the `loose` parameter -// TODO support SemVer instances as input parameters -declare module 'semver' { - declare type Release = - 'major' | - 'premajor' | - 'minor' | - 'preminor' | - 'patch' | - 'prepatch' | - 'prerelease'; - - // The supported comparators are taken from the source here: - // https://github.com/npm/node-semver/blob/8bd070b550db2646362c9883c8d008d32f66a234/semver.js#L623 - declare type Comparator = - '===' | - '!==' | - '==' | - '=' | - '' | // Not sure why you would want this, but whatever. - '!=' | - '>' | - '>=' | - '<' | - '<='; - - declare class SemVer { - loose: ?boolean, - raw: string, - major: number, - minor: number, - patch: number, - prerelease: Array, - build: Array, - version: string, - } - - // Functions - declare function valid(v: string): string | null; - declare function inc(v: string, release: Release): string | null; - declare function major(v: string): number; - declare function minor(v: string): number; - declare function patch(v: string): number; - - // Comparison - declare function gt(v1: string, v2: string): boolean; - declare function gte(v1: string, v2: string): boolean; - declare function lt(v1: string, v2: string): boolean; - declare function lte(v1: string, v2: string): boolean; - declare function eq(v1: string, v2: string): boolean; - declare function neq(v1: string, v2: string): boolean; - declare function cmp(v1: string, comparator: Comparator, v2: string): boolean; - declare function compare(v1: string, v2: string): -1 | 0 | 1; - declare function rcompare(v1: string, v2: string): -1 | 0 | 1; - declare function diff(v1: string, v2: string): ?Release; - - // Ranges - declare function validRange(r: string): string | null; - declare function satisfies(version: string, range: string): boolean; - declare function maxSatisfying(versions: Array, range: string): string | null; - declare function gtr(version: string, range: string): boolean; - declare function ltr(version: string, range: string): boolean; - declare function outside(version: string, range: string, hilo: '>' | '<'): boolean; - - // Not explicitly documented - declare function parse(version: string): ?SemVer; -} diff --git a/lib/main.js b/lib/main.js index e95dea38a1..8010c9306d 100644 --- a/lib/main.js +++ b/lib/main.js @@ -1,12 +1,59 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the license found in the LICENSE file in - * the root directory of this source tree. - * - * @flow - */ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.config = undefined; +exports.activate = activate; +exports.deactivate = deactivate; +exports.serialize = serialize; + +require('./preload-dependencies'); + +var _featureConfig; + +function _load_featureConfig() { + return _featureConfig = _interopRequireDefault(require('../pkg/commons-atom/featureConfig')); +} + +var _fs = _interopRequireDefault(require('fs')); + +var _path = _interopRequireDefault(require('path')); + +var _serviceManager; + +function _load_serviceManager() { + return _serviceManager = require('../pkg/nuclide-remote-connection/lib/service-manager'); +} + +var _electron = _interopRequireDefault(require('electron')); + +var _atom = require('atom'); + +var _atomPackageDeps; + +function _load_atomPackageDeps() { + return _atomPackageDeps = require('atom-package-deps'); +} + +var _package; + +function _load_package() { + return _package = _interopRequireDefault(require('../package.json')); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +// eslint-disable-next-line nuclide-internal/prefer-nuclide-uri +const { remote } = _electron.default; /** + * Copyright (c) 2015-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the license found in the LICENSE file in + * the root directory of this source tree. + * + * + */ /** * _ _ _ _ ____ _ _ ___ ____ @@ -20,21 +67,9 @@ /* global localStorage */ -import './preload-dependencies'; - -import featureConfig from '../pkg/commons-atom/featureConfig'; -import fs from 'fs'; -import invariant from 'assert'; -// eslint-disable-next-line nuclide-internal/prefer-nuclide-uri -import path from 'path'; -import {setUseLocalRpc} from '../pkg/nuclide-remote-connection/lib/service-manager'; -import electron from 'electron'; -import {CompositeDisposable} from 'atom'; -import {install as atomPackageDepsInstall} from 'atom-package-deps'; -import nuclidePackageJson from '../package.json'; - -const {remote} = electron; -invariant(remote != null); +if (!(remote != null)) { + throw new Error('Invariant violation: "remote != null"'); +} // Add a dummy deserializer. This forces Atom to load Nuclide's main module // (this file) when the package is loaded, which is super important because @@ -46,47 +81,40 @@ invariant(remote != null); // features would never load again! // // [1] https://github.com/atom/atom/blob/v1.9.8/src/package.coffee#L442 + + atom.deserializers.add({ name: 'nuclide.ForceMainModuleLoad', - deserialize() {}, + deserialize() {} }); // Exported "config" object -export const config = { +const config = exports.config = { installRecommendedPackages: { default: false, - description: - 'On start up, check for and install Atom packages recommended for use with Nuclide. The' - + ' list of packages can be found in the package-deps setting in this package\'s' - + ' "package.json" file. Disabling this setting will not uninstall packages it previously' - + ' installed. Restart Atom after changing this setting for it to take effect.', + description: 'On start up, check for and install Atom packages recommended for use with Nuclide. The' + ' list of packages can be found in the package-deps setting in this package\'s' + ' "package.json" file. Disabling this setting will not uninstall packages it previously' + ' installed. Restart Atom after changing this setting for it to take effect.', title: 'Install Recommended Packages on Startup', - type: 'boolean', + type: 'boolean' }, useLocalRpc: { default: false, - description: - 'Use RPC marshalling for local services. This ensures better compatibility between the local' - + ' and remote case. Useful for internal Nuclide development. Requires restart to take' - + ' effect.', + description: 'Use RPC marshalling for local services. This ensures better compatibility between the local' + ' and remote case. Useful for internal Nuclide development. Requires restart to take' + ' effect.', title: 'Use RPC for local Services.', - type: 'boolean', + type: 'boolean' }, use: { type: 'object', - properties: {}, - }, + properties: {} + } }; // `setUseLocalRpc` can only be called once, so it's set out here during load. const _useLocalRpc = atom.config.get('nuclide.useLocalRpc'); -const _shouldUseLocalRpc = typeof _useLocalRpc !== 'boolean' - ? config.useLocalRpc.default - : _useLocalRpc; -setUseLocalRpc(_shouldUseLocalRpc); +const _shouldUseLocalRpc = typeof _useLocalRpc !== 'boolean' ? config.useLocalRpc.default : _useLocalRpc; +(0, (_serviceManager || _load_serviceManager()).setUseLocalRpc)(_shouldUseLocalRpc); // Nuclide packages for Atom are called "features" -const FEATURES_DIR = path.join(__dirname, '../pkg'); +const FEATURES_DIR = _path.default.join(__dirname, '../pkg'); const features = {}; let disposables; @@ -94,33 +122,39 @@ let disposables; /** * Get the "package.json" of all the features. */ -fs.readdirSync(FEATURES_DIR).forEach(item => { +_fs.default.readdirSync(FEATURES_DIR).forEach(item => { // Optimization: Our directories don't have periods - this must be a file if (item.indexOf('.') !== -1) { return; } - const dirname = path.join(FEATURES_DIR, item); - const filename = path.join(dirname, 'package.json'); + const dirname = _path.default.join(FEATURES_DIR, item); + const filename = _path.default.join(dirname, 'package.json'); try { - const stat = fs.statSync(filename); - invariant(stat.isFile()); + const stat = _fs.default.statSync(filename); + + if (!stat.isFile()) { + throw new Error('Invariant violation: "stat.isFile()"'); + } } catch (err) { if (err && err.code === 'ENOENT') { return; } } - const src = fs.readFileSync(filename, 'utf8'); + const src = _fs.default.readFileSync(filename, 'utf8'); // Optimization: Avoid JSON parsing if it can't reasonably be an Atom package if (src.indexOf('"Atom"') === -1) { return; } const pkg = JSON.parse(src); if (pkg.nuclide && pkg.nuclide.packageType === 'Atom') { - invariant(pkg.name); + if (!pkg.name) { + throw new Error('Invariant violation: "pkg.name"'); + } + features[pkg.name] = { pkg, dirname, - useKeyPath: `nuclide.use.${pkg.name}`, + useKeyPath: `nuclide.use.${pkg.name}` }; } }); @@ -134,7 +168,7 @@ fs.readdirSync(FEATURES_DIR).forEach(item => { * https://atom.io/docs/api/latest/Config */ Object.keys(features).forEach(name => { - const {pkg} = features[name]; + const { pkg } = features[name]; // Sample packages are disabled by default. They are meant for development // use only, and aren't included in Nuclide builds. @@ -145,7 +179,7 @@ Object.keys(features).forEach(name => { title: `Enable the "${name}" feature`, description: pkg.description || '', type: 'boolean', - default: enabled, + default: enabled }; if (pkg.providedServices) { const provides = Object.keys(pkg.providedServices).join(', '); @@ -162,13 +196,12 @@ Object.keys(features).forEach(name => { if (pkgConfig) { config[name] = { type: 'object', - properties: {}, + properties: {} }; Object.keys(pkgConfig).forEach(key => { - config[name].properties[key] = { - ...pkgConfig[key], - title: (pkgConfig[key].title || key), - }; + config[name].properties[key] = Object.assign({}, pkgConfig[key], { + title: pkgConfig[key].title || key + }); }); } }); @@ -178,7 +211,9 @@ Object.keys(features).forEach(name => { // happen before Nuclide's. So we wait until Nuclide is done loading, but before // it activates, to load the features. let initialLoadDisposable = atom.packages.onDidLoadPackage(pack => { - if (pack.name !== 'nuclide') { return; } + if (pack.name !== 'nuclide') { + return; + } // Load all the features. This needs to be done during Atom's load phase to // make sure that deserializers are registered, etc. @@ -190,46 +225,47 @@ let initialLoadDisposable = atom.packages.onDidLoadPackage(pack => { // this point `atom.config.get` returns the user set value. If it's // `undefined`, then the user has not set it. const _enabled = atom.config.get(feature.useKeyPath); - const _shouldEnable = typeof _enabled === 'undefined' - ? config.use.properties[name].default - : _enabled; + const _shouldEnable = typeof _enabled === 'undefined' ? config.use.properties[name].default : _enabled; if (_shouldEnable) { atom.packages.loadPackage(feature.dirname); } }); - invariant(initialLoadDisposable != null); + if (!(initialLoadDisposable != null)) { + throw new Error('Invariant violation: "initialLoadDisposable != null"'); + } + initialLoadDisposable.dispose(); initialLoadDisposable = null; }); -export function activate() { +function activate() { const nuclidePack = atom.packages.getLoadedPackage('nuclide'); - invariant(nuclidePack != null); + + if (!(nuclidePack != null)) { + throw new Error('Invariant violation: "nuclidePack != null"'); + } // This is a failsafe in case the `nuclide.ForceMainModuleLoad` deserializer // defined above does not register in time, or if the defer key has been set // w/o our knowledge. This can happen during OSS upgrades. - localStorage.removeItem( - nuclidePack.getCanDeferMainModuleRequireStorageKey(), - ); - disposables = new CompositeDisposable(); + + localStorage.removeItem(nuclidePack.getCanDeferMainModuleRequireStorageKey()); + + disposables = new _atom.CompositeDisposable(); // Add the "Nuclide" menu, if it's not there already. - disposables.add( - atom.menu.add([{ - label: 'Nuclide', - submenu: [{ - label: `Version ${nuclidePackageJson.version}`, - enabled: false, - }], - }]), - ); + disposables.add(atom.menu.add([{ + label: 'Nuclide', + submenu: [{ + label: `Version ${(_package || _load_package()).default.version}`, + enabled: false + }] + }])); // Manually manipulate the menu template order. - const insertIndex = - atom.menu.template.findIndex(item => item.role === 'window' || item.role === 'help'); + const insertIndex = atom.menu.template.findIndex(item => item.role === 'window' || item.role === 'help'); if (insertIndex !== -1) { const nuclideIndex = atom.menu.template.findIndex(item => item.label === 'Nuclide'); const menuItem = atom.menu.template.splice(nuclideIndex, 1)[0]; @@ -261,37 +297,45 @@ export function activate() { safeDeactivate(name); } }); - invariant(disposables != null); + + if (!(disposables != null)) { + throw new Error('Invariant violation: "disposables != null"'); + } + disposables.add(watcher); }); // Install public, 3rd-party Atom packages listed in this package's 'package-deps' setting. Run // this *after* other packages are activated so they can modify this setting if desired before // installation is attempted. - if (featureConfig.get('installRecommendedPackages')) { + if ((_featureConfig || _load_featureConfig()).default.get('installRecommendedPackages')) { // Workaround for restoring multiple Atom windows. This prevents having all // the windows trying to install the deps at the same time - often clobbering // each other's install. const firstWindowId = remote.BrowserWindow.getAllWindows()[0].id; const currentWindowId = remote.getCurrentWindow().id; if (firstWindowId === currentWindowId) { - atomPackageDepsInstall('nuclide'); + (0, (_atomPackageDeps || _load_atomPackageDeps()).install)('nuclide'); } } } -export function deactivate() { +function deactivate() { Object.keys(features).forEach(name => { // Deactivate the packge, but don't serialize. That needs to be done in a separate phase so that // we don't end up disconnecting a service and then serializing the disconnected state. safeDeactivate(name, true); }); - invariant(disposables != null); + + if (!(disposables != null)) { + throw new Error('Invariant violation: "disposables != null"'); + } + disposables.dispose(); disposables = null; } -export function serialize() { +function serialize() { // When Nuclide is serialized, all of its features need to be serialized. This is an abuse of // `serialize()` since we're using it to do side effects instead of returning the serialization, // but it ensures that serialization of the Atom packages happens at the right point in the @@ -323,4 +367,4 @@ function safeSerialize(name) { // eslint-disable-next-line no-console console.error(`Error serializing "${name}": ${err.message}`); } -} +} \ No newline at end of file diff --git a/lib/preload-dependencies.js b/lib/preload-dependencies.js index 92397177ba..cf8d850975 100644 --- a/lib/preload-dependencies.js +++ b/lib/preload-dependencies.js @@ -1,3 +1,5 @@ +'use strict'; + /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,7 +7,7 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * */ /** @@ -25,7 +27,7 @@ require('log4js'); require('react-for-atom').React; require('react-for-atom').ReactDOM; require('redux'); -require('rxjs'); +require('rxjs/bundles/Rx.min.js'); // Single out fs-plus since we can probably remove it one day. -require('fs-plus'); +require('fs-plus'); \ No newline at end of file diff --git a/lib/test-runner.js b/lib/test-runner.js index 583e7edaf5..1e6890f336 100644 --- a/lib/test-runner.js +++ b/lib/test-runner.js @@ -1,3 +1,21 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _asyncToGenerator = _interopRequireDefault(require('async-to-generator')); + +var _console = require('console'); + +var _electron = _interopRequireDefault(require('electron')); + +var _fs = _interopRequireDefault(require('fs')); + +var _path = _interopRequireDefault(require('path')); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,121 +23,127 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * */ -import type {TestRunnerParams, ExitCode} from './types'; - -import invariant from 'assert'; -import {Console} from 'console'; -import electron from 'electron'; -import fs from 'fs'; +const { ipcRenderer } = _electron.default; // eslint-disable-next-line nuclide-internal/prefer-nuclide-uri -import path from 'path'; -const {ipcRenderer} = electron; -invariant(ipcRenderer != null); +if (!(ipcRenderer != null)) { + throw new Error('Invariant violation: "ipcRenderer != null"'); +} // When chromiums verbosity is off, patch `console` to output through the main // process. `--v=-3` is used by the CI. + + if (process.argv.indexOf('--v=-3')) { // https://github.com/nodejs/node/blob/v5.1.1/lib/console.js - global.console = new Console( - /* stdout */ {write(chunk) { ipcRenderer.send('write-to-stdout', chunk); }}, - /* stderr */ {write(chunk) { ipcRenderer.send('write-to-stderr', chunk); }}, - ); + global.console = new _console.Console( + /* stdout */{ write(chunk) { + ipcRenderer.send('write-to-stdout', chunk); + } }, + /* stderr */{ write(chunk) { + ipcRenderer.send('write-to-stderr', chunk); + } }); } -const integrationTestsDir = path.join(__dirname, '../spec'); +const integrationTestsDir = _path.default.join(__dirname, '../spec'); -export default async function(params: TestRunnerParams): Promise { - const isIntegrationTest = params.testPaths - .some(testPath => testPath.startsWith(integrationTestsDir)); - const isApmTest = !isIntegrationTest; +exports.default = (() => { + var _ref = (0, _asyncToGenerator.default)(function* (params) { + const isIntegrationTest = params.testPaths.some(function (testPath) { + return testPath.startsWith(integrationTestsDir); + }); + const isApmTest = !isIntegrationTest; - // It's assumed that all of the tests belong to the same package. - const pkg = getPackage(params.testPaths[0]); - if (pkg == null) { - throw new Error(`Couldn't find a parent "package.json" for ${params.testPaths[0]}`); - } - const nuclideConfig = pkg.nuclide && pkg.nuclide.config; - - const statusCode = await params.legacyTestRunner({ - logFile: params.logFile, - headless: params.headless, - testPaths: params.testPaths, - buildAtomEnvironment(buildEnvParams) { - const atomGlobal = params.buildAtomEnvironment(buildEnvParams); - - if (isIntegrationTest) { - jasmine.getEnv().beforeEach(() => { - // If we're running integration tests in parallel, double the timeout. - if (process.env.SANDCASTLE === '1') { - jasmine.getEnv().defaultTimeoutInterval = 10000; - } - // `atom.confirm` blocks Atom and stops the integration tests. - spyOn(atomGlobal, 'confirm'); - // Ensure 3rd-party packages are not installed via the - // 'atom-package-deps' package when the 'nuclide' package is activated. - // They are assumed to be already in ~/.atom/packages. js_test_runner.py - // handles installing them during automated testing. - atomGlobal.config.set('nuclide.installRecommendedPackages', false); - }); + // It's assumed that all of the tests belong to the same package. + const pkg = getPackage(params.testPaths[0]); + if (pkg == null) { + throw new Error(`Couldn't find a parent "package.json" for ${params.testPaths[0]}`); + } + const nuclideConfig = pkg.nuclide && pkg.nuclide.config; + + const statusCode = yield params.legacyTestRunner({ + logFile: params.logFile, + headless: params.headless, + testPaths: params.testPaths, + buildAtomEnvironment(buildEnvParams) { + const atomGlobal = params.buildAtomEnvironment(buildEnvParams); + + if (isIntegrationTest) { + jasmine.getEnv().beforeEach(() => { + // If we're running integration tests in parallel, double the timeout. + if (process.env.SANDCASTLE === '1') { + jasmine.getEnv().defaultTimeoutInterval = 10000; + } + // `atom.confirm` blocks Atom and stops the integration tests. + spyOn(atomGlobal, 'confirm'); + // Ensure 3rd-party packages are not installed via the + // 'atom-package-deps' package when the 'nuclide' package is activated. + // They are assumed to be already in ~/.atom/packages. js_test_runner.py + // handles installing them during automated testing. + atomGlobal.config.set('nuclide.installRecommendedPackages', false); + }); - jasmine.getEnv().afterEach(() => { - if (atomGlobal.confirm.calls.length) { - const details = atomGlobal.confirm.argsForCall - .map((args, i) => `call #${i} with ${JSON.stringify(args)}`); - throw new Error('atom.confirm was called.\n' + details); - } - }); - } + jasmine.getEnv().afterEach(() => { + if (atomGlobal.confirm.calls.length) { + const details = atomGlobal.confirm.argsForCall.map((args, i) => `call #${i} with ${JSON.stringify(args)}`); + throw new Error('atom.confirm was called.\n' + details); + } + }); + } - if (isApmTest && nuclideConfig) { - jasmine.getEnv().beforeEach(() => { - // Since the UP loader creates the config for all feature packages, - // and it doesn't load for unit tests, it's necessary to manually - // construct any default config that they define. - Object.keys(nuclideConfig).forEach(key => { - atomGlobal.config.setSchema(`nuclide.${pkg.name}.${key}`, nuclideConfig[key]); + if (isApmTest && nuclideConfig) { + jasmine.getEnv().beforeEach(() => { + // Since the UP loader creates the config for all feature packages, + // and it doesn't load for unit tests, it's necessary to manually + // construct any default config that they define. + Object.keys(nuclideConfig).forEach(key => { + atomGlobal.config.setSchema(`nuclide.${pkg.name}.${key}`, nuclideConfig[key]); + }); }); + } + + return atomGlobal; + } + }); + + yield new Promise(function (resolve) { + const temp = require('temp'); + if (statusCode === 0) { + // Atom intercepts "process.exit" so we have to do our own manual cleanup. + temp.cleanup(function (err, stats) { + resolve(); + if (err && err.message !== 'not tracking') { + // eslint-disable-next-line no-console + console.log(`temp.cleanup() failed. ${err}`); + } }); + } else { + // When the test fails, we keep the temp contents for debugging. + temp.track(false); + resolve(); } + }); - return atomGlobal; - }, - }); - - await new Promise(resolve => { - const temp = require('temp'); - if (statusCode === 0) { - // Atom intercepts "process.exit" so we have to do our own manual cleanup. - temp.cleanup((err, stats) => { - resolve(); - if (err && err.message !== 'not tracking') { - // eslint-disable-next-line no-console - console.log(`temp.cleanup() failed. ${err}`); - } - }); - } else { - // When the test fails, we keep the temp contents for debugging. - temp.track(false); - resolve(); - } + return statusCode; }); - return statusCode; -} + return function (_x) { + return _ref.apply(this, arguments); + }; +})(); function getPackage(start) { - let current = path.resolve(start); + let current = _path.default.resolve(start); while (true) { - const filename = path.join(current, 'package.json'); - if (fs.existsSync(filename)) { - return JSON.parse(fs.readFileSync(filename, 'utf8')); + const filename = _path.default.join(current, 'package.json'); + if (_fs.default.existsSync(filename)) { + return JSON.parse(_fs.default.readFileSync(filename, 'utf8')); } else { - const next = path.join(current, '..'); + const next = _path.default.join(current, '..'); if (next === current) { return null; } else { @@ -128,3 +152,4 @@ function getPackage(start) { } } } +module.exports = exports['default']; \ No newline at end of file diff --git a/lib/types.js b/lib/types.js index d1755ff686..9a390c31f7 100644 --- a/lib/types.js +++ b/lib/types.js @@ -1,43 +1 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the license found in the LICENSE file in - * the root directory of this source tree. - * - * @flow - */ - -// http://flight-manual.atom.io/hacking-atom/sections/writing-specs/#customizing-your-test-runner -export type TestRunnerParams = { - /** Absolute paths to tests to run. Could be paths to files or directories. */ - testPaths: Array, - /** Creates the `atom` global object. */ - buildAtomEnvironment: (params: BuildAtomEnvironmentParams) => AtomGlobal, - /** Currently undocumnted, but seemingly necessary to use buildAtomEnvironment(). */ - buildDefaultApplicationDelegate: () => Object, - /** An optional path to a log file to which test output should be logged. */ - logFile: ?string, - /** A boolean indicating whether or not the tests are running headless. */ - headless: boolean, - /** The legacy Jasmine runner */ - legacyTestRunner: (params: LegacyTestRunnerParams) => Promise, -}; - -// https://github.com/atom/atom/blob/v1.6.2/spec/jasmine-test-runner.coffee -export type LegacyTestRunnerParams = { - logFile: ?string, - headless: boolean, - testPaths: Array, - buildAtomEnvironment: (params: BuildAtomEnvironmentParams) => AtomGlobal, -}; - -export type BuildAtomEnvironmentParams = { - applicationDelegate: Object, - window: Object, - document: Object, - configDirPath?: string, - enablePersistence?: boolean, -}; - -export type ExitCode = number; +"use strict"; \ No newline at end of file diff --git a/lib/url-main.js b/lib/url-main.js index a58d44e76e..5d9b1cef56 100644 --- a/lib/url-main.js +++ b/lib/url-main.js @@ -1,3 +1,74 @@ +'use strict'; + +var _asyncToGenerator = _interopRequireDefault(require('async-to-generator')); + +// This function gets called by the Atom package-level URL handler. +// Normally this is expected to set up the Atom application window. +let initialize = (() => { + var _ref = (0, _asyncToGenerator.default)(function* (blobStore) { + const currentWindow = remote.getCurrentWindow(); + try { + const { urlToOpen } = getLoadSettings(); + const { host, pathname, query } = _url.default.parse(urlToOpen); + + if (!(host === 'nuclide' && pathname != null && pathname !== '')) { + throw new Error(`Invalid URL ${urlToOpen}`); + } + + const message = pathname.substr(1); + const params = _querystring.default.parse(query || ''); + + // Prefer the focused window, but any existing window. + // The parent window is used for testing only. + const existingWindow = currentWindow.getParentWindow() || remote.BrowserWindow.getFocusedWindow() || remote.BrowserWindow.getAllWindows().filter(function (x) { + return x.id !== currentWindow.id; + })[0]; + if (existingWindow == null) { + // Prevent multiple windows from being opened when URIs are opened too quickly. + if (!acquireLock()) { + throw new Error('Another URI is already being opened.'); + } + + // Restore the user's previous windows. + // The real Atom initialization script will be run in the current window. + + + restoreWindows(blobStore); + + // Wait for Nuclide to activate (so the event below gets handled). + yield new Promise(function (resolve) { + atom.packages.onDidActivateInitialPackages(resolve); + }); + + currentWindow.webContents.send(CHANNEL, { message, params }); + releaseLock(); + } else { + existingWindow.webContents.send(CHANNEL, { message, params }); + // Atom has various handlers that block window closing. + currentWindow.destroy(); + } + } catch (err) { + remote.dialog.showErrorBox('Could not open URL', err.stack); + releaseLock(); + currentWindow.destroy(); + } + }); + + return function initialize(_x) { + return _ref.apply(this, arguments); + }; +})(); + +var _electron = _interopRequireDefault(require('electron')); + +var _path = _interopRequireDefault(require('path')); + +var _querystring = _interopRequireDefault(require('querystring')); + +var _url = _interopRequireDefault(require('url')); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,7 +76,7 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * */ /** @@ -24,22 +95,19 @@ /* global localStorage */ -import electron from 'electron'; -import invariant from 'invariant'; +const { remote } = _electron.default; // eslint-disable-next-line nuclide-internal/prefer-nuclide-uri -import path from 'path'; -import querystring from 'querystring'; -import url from 'url'; -const {remote} = electron; -invariant(remote != null, 'for Flow'); +if (!(remote != null)) { + throw new Error('for Flow'); +} const CHANNEL = 'nuclide-url-open'; // https://github.com/atom/atom/blob/master/src/window-load-settings-helpers.coffee // We can't use this directly since the resourcePath is specified from loadSettings. let loadSettings; -function getLoadSettings(): Object { +function getLoadSettings() { if (loadSettings === undefined) { loadSettings = JSON.parse(decodeURIComponent(document.location.hash.substr(1))); } @@ -48,39 +116,35 @@ function getLoadSettings(): Object { // Contains initialPaths for each previously-running Atom window. // Atom can handle retrieving the more detailed state by itself. -function getApplicationState(home: string): ?Array { +function getApplicationState(home) { // $FlowIgnore - const StorageFolder = require(path.join( - getLoadSettings().resourcePath, - 'src/storage-folder.js', - )); + const StorageFolder = require(_path.default.join(getLoadSettings().resourcePath, 'src/storage-folder.js')); return new StorageFolder(home).load('application.json'); } // This is the function that Atom normally calls to initialize a new window. // By calling it, we can simulate starting up a regular Atom window. function getAtomInitializerScript() { - return path.join( - getLoadSettings().resourcePath, - 'src/initialize-application-window.js', - ); + return _path.default.join(getLoadSettings().resourcePath, 'src/initialize-application-window.js'); } // Read the previous window state and create Atom windows as appropriate. -function restoreWindows(blobStore: Object): void { - invariant(process.env.ATOM_HOME, 'ATOM_HOME not found'); +function restoreWindows(blobStore) { + if (!process.env.ATOM_HOME) { + throw new Error('ATOM_HOME not found'); + } + const windowStates = getApplicationState(process.env.ATOM_HOME) || []; const initScript = getAtomInitializerScript(); // Modify some of the load settings to match a real Atom window. - document.location.hash = encodeURIComponent(JSON.stringify({ - ...getLoadSettings(), + document.location.hash = encodeURIComponent(JSON.stringify(Object.assign({}, getLoadSettings(), { // Replace the initialization script so reloading works. windowInitializationScript: initScript, // Inherit the initialPaths from the first state. // We need to set this before initializing Atom to restore the state. - initialPaths: windowStates[0] != null && windowStates[0].initialPaths || [], - })); + initialPaths: windowStates[0] != null && windowStates[0].initialPaths || [] + }))); // Start up a real Atom instance in the current window. // Note that the `atom` global becomes accessible synchronously. @@ -89,14 +153,14 @@ function restoreWindows(blobStore: Object): void { for (const windowState of windowStates.slice(1)) { const initialPaths = windowState.initialPaths || []; - atom.open({initialPaths, pathsToOpen: initialPaths}); + atom.open({ initialPaths, pathsToOpen: initialPaths }); } } const LOCK_KEY = CHANNEL + '.lock'; const LOCK_TIMEOUT = 10000; -function acquireLock(): boolean { +function acquireLock() { // localStorage.set/getItem is not truly atomic, so this is not actually sound. // However, it should be fast enough to cover the use case of human clicks. const lockTime = localStorage.getItem(LOCK_KEY); @@ -107,57 +171,10 @@ function acquireLock(): boolean { return true; } -function releaseLock(): void { +function releaseLock() { localStorage.removeItem(LOCK_KEY); } -// This function gets called by the Atom package-level URL handler. -// Normally this is expected to set up the Atom application window. -async function initialize(blobStore: Object): Promise { - const currentWindow = remote.getCurrentWindow(); - try { - const {urlToOpen} = getLoadSettings(); - const {host, pathname, query} = url.parse(urlToOpen); - invariant( - host === 'nuclide' && pathname != null && pathname !== '', - `Invalid URL ${urlToOpen}`, - ); - - const message = pathname.substr(1); - const params = querystring.parse(query || ''); - - // Prefer the focused window, but any existing window. - // The parent window is used for testing only. - const existingWindow = currentWindow.getParentWindow() || - remote.BrowserWindow.getFocusedWindow() || - remote.BrowserWindow.getAllWindows().filter(x => x.id !== currentWindow.id)[0]; - if (existingWindow == null) { - // Prevent multiple windows from being opened when URIs are opened too quickly. - invariant(acquireLock(), 'Another URI is already being opened.'); - - // Restore the user's previous windows. - // The real Atom initialization script will be run in the current window. - restoreWindows(blobStore); - - // Wait for Nuclide to activate (so the event below gets handled). - await new Promise(resolve => { - atom.packages.onDidActivateInitialPackages(resolve); - }); - - currentWindow.webContents.send(CHANNEL, {message, params}); - releaseLock(); - } else { - existingWindow.webContents.send(CHANNEL, {message, params}); - // Atom has various handlers that block window closing. - currentWindow.destroy(); - } - } catch (err) { - remote.dialog.showErrorBox('Could not open URL', err.stack); - releaseLock(); - currentWindow.destroy(); - } -} - module.exports = initialize; // Exported for testing. @@ -166,5 +183,5 @@ module.exports.__test__ = { getApplicationState, getAtomInitializerScript, acquireLock, - releaseLock, -}; + releaseLock +}; \ No newline at end of file diff --git a/npm-shrinkwrap.json b/npm-shrinkwrap.json index 1a1268c2c8..c771eaaeba 100644 --- a/npm-shrinkwrap.json +++ b/npm-shrinkwrap.json @@ -2,57 +2,6 @@ "name": "nuclide", "version": "0.203.0", "dependencies": { - "abbrev": { - "version": "1.0.9", - "from": "abbrev@>=1.0.0 <2.0.0", - "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.0.9.tgz", - "dev": true - }, - "acorn": { - "version": "4.0.4", - "from": "acorn@>=4.0.1 <5.0.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-4.0.4.tgz", - "dev": true - }, - "acorn-jsx": { - "version": "3.0.1", - "from": "acorn-jsx@>=3.0.0 <4.0.0", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-3.0.1.tgz", - "dev": true, - "dependencies": { - "acorn": { - "version": "3.3.0", - "from": "acorn@>=3.0.4 <4.0.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz", - "dev": true - } - } - }, - "ajv": { - "version": "4.11.2", - "from": "ajv@>=4.7.0 <5.0.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-4.11.2.tgz", - "dev": true - }, - "ajv-keywords": { - "version": "1.5.1", - "from": "ajv-keywords@>=1.0.0 <2.0.0", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-1.5.1.tgz", - "dev": true - }, - "amdefine": { - "version": "1.0.1", - "from": "amdefine@>=0.0.4", - "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz", - "dev": true, - "optional": true - }, - "ansi-escapes": { - "version": "1.4.0", - "from": "ansi-escapes@>=1.1.0 <2.0.0", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-1.4.0.tgz", - "dev": true - }, "ansi-regex": { "version": "2.1.1", "from": "ansi-regex@>=2.0.0 <3.0.0", @@ -83,24 +32,6 @@ "from": "array-reduce@>=0.0.0 <0.1.0", "resolved": "https://registry.npmjs.org/array-reduce/-/array-reduce-0.0.0.tgz" }, - "array-union": { - "version": "1.0.2", - "from": "array-union@>=1.0.1 <2.0.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", - "dev": true - }, - "array-uniq": { - "version": "1.0.3", - "from": "array-uniq@>=1.0.1 <2.0.0", - "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", - "dev": true - }, - "arrify": { - "version": "1.0.1", - "from": "arrify@>=1.0.0 <2.0.0", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", - "dev": true - }, "asap": { "version": "2.0.5", "from": "asap@>=2.0.3 <2.1.0", @@ -131,12 +62,6 @@ "from": "asynckit@>=0.4.0 <0.5.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz" }, - "atom-grammar-test": { - "version": "0.6.3", - "from": "atom-grammar-test@0.6.3", - "resolved": "https://registry.npmjs.org/atom-grammar-test/-/atom-grammar-test-0.6.3.tgz", - "dev": true - }, "atom-package-deps": { "version": "4.3.1", "from": "atom-package-deps@4.3.1", @@ -162,198 +87,6 @@ "from": "aws4@>=1.2.1 <2.0.0", "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.5.0.tgz" }, - "babel-code-frame": { - "version": "6.22.0", - "from": "babel-code-frame@>=6.22.0 <7.0.0", - "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.22.0.tgz", - "dev": true - }, - "babel-core": { - "version": "6.22.1", - "from": "babel-core@6.22.1", - "resolved": "https://registry.npmjs.org/babel-core/-/babel-core-6.22.1.tgz", - "dev": true - }, - "babel-eslint": { - "version": "7.1.1", - "from": "babel-eslint@7.1.1", - "resolved": "https://registry.npmjs.org/babel-eslint/-/babel-eslint-7.1.1.tgz", - "dev": true - }, - "babel-generator": { - "version": "6.22.0", - "from": "babel-generator@6.22.0", - "resolved": "https://registry.npmjs.org/babel-generator/-/babel-generator-6.22.0.tgz", - "dev": true - }, - "babel-helper-builder-react-jsx": { - "version": "6.22.0", - "from": "babel-helper-builder-react-jsx@>=6.22.0 <7.0.0", - "resolved": "https://registry.npmjs.org/babel-helper-builder-react-jsx/-/babel-helper-builder-react-jsx-6.22.0.tgz", - "dev": true - }, - "babel-helper-function-name": { - "version": "6.22.0", - "from": "babel-helper-function-name@>=6.22.0 <7.0.0", - "resolved": "https://registry.npmjs.org/babel-helper-function-name/-/babel-helper-function-name-6.22.0.tgz", - "dev": true - }, - "babel-helper-get-function-arity": { - "version": "6.22.0", - "from": "babel-helper-get-function-arity@>=6.22.0 <7.0.0", - "resolved": "https://registry.npmjs.org/babel-helper-get-function-arity/-/babel-helper-get-function-arity-6.22.0.tgz", - "dev": true - }, - "babel-helper-remap-async-to-generator": { - "version": "6.22.0", - "from": "babel-helper-remap-async-to-generator@>=6.22.0 <7.0.0", - "resolved": "https://registry.npmjs.org/babel-helper-remap-async-to-generator/-/babel-helper-remap-async-to-generator-6.22.0.tgz", - "dev": true - }, - "babel-helpers": { - "version": "6.22.0", - "from": "babel-helpers@>=6.22.0 <7.0.0", - "resolved": "https://registry.npmjs.org/babel-helpers/-/babel-helpers-6.22.0.tgz", - "dev": true - }, - "babel-messages": { - "version": "6.22.0", - "from": "babel-messages@>=6.22.0 <7.0.0", - "resolved": "https://registry.npmjs.org/babel-messages/-/babel-messages-6.22.0.tgz", - "dev": true - }, - "babel-plugin-add-module-exports": { - "version": "0.2.1", - "from": "babel-plugin-add-module-exports@0.2.1", - "resolved": "https://registry.npmjs.org/babel-plugin-add-module-exports/-/babel-plugin-add-module-exports-0.2.1.tgz", - "dev": true - }, - "babel-plugin-check-es2015-constants": { - "version": "6.22.0", - "from": "babel-plugin-check-es2015-constants@6.22.0", - "resolved": "https://registry.npmjs.org/babel-plugin-check-es2015-constants/-/babel-plugin-check-es2015-constants-6.22.0.tgz", - "dev": true - }, - "babel-plugin-syntax-async-functions": { - "version": "6.13.0", - "from": "babel-plugin-syntax-async-functions@>=6.8.0 <7.0.0", - "resolved": "https://registry.npmjs.org/babel-plugin-syntax-async-functions/-/babel-plugin-syntax-async-functions-6.13.0.tgz", - "dev": true - }, - "babel-plugin-syntax-class-properties": { - "version": "6.13.0", - "from": "babel-plugin-syntax-class-properties@>=6.8.0 <7.0.0", - "resolved": "https://registry.npmjs.org/babel-plugin-syntax-class-properties/-/babel-plugin-syntax-class-properties-6.13.0.tgz", - "dev": true - }, - "babel-plugin-syntax-flow": { - "version": "6.18.0", - "from": "babel-plugin-syntax-flow@>=6.18.0 <7.0.0", - "resolved": "https://registry.npmjs.org/babel-plugin-syntax-flow/-/babel-plugin-syntax-flow-6.18.0.tgz", - "dev": true - }, - "babel-plugin-syntax-jsx": { - "version": "6.18.0", - "from": "babel-plugin-syntax-jsx@>=6.8.0 <7.0.0", - "resolved": "https://registry.npmjs.org/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz", - "dev": true - }, - "babel-plugin-syntax-object-rest-spread": { - "version": "6.13.0", - "from": "babel-plugin-syntax-object-rest-spread@>=6.8.0 <7.0.0", - "resolved": "https://registry.npmjs.org/babel-plugin-syntax-object-rest-spread/-/babel-plugin-syntax-object-rest-spread-6.13.0.tgz", - "dev": true - }, - "babel-plugin-transform-async-to-module-method": { - "version": "6.22.0", - "from": "babel-plugin-transform-async-to-module-method@6.22.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-async-to-module-method/-/babel-plugin-transform-async-to-module-method-6.22.0.tgz", - "dev": true - }, - "babel-plugin-transform-class-properties": { - "version": "6.22.0", - "from": "babel-plugin-transform-class-properties@6.22.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-class-properties/-/babel-plugin-transform-class-properties-6.22.0.tgz", - "dev": true - }, - "babel-plugin-transform-es2015-modules-commonjs": { - "version": "6.22.0", - "from": "babel-plugin-transform-es2015-modules-commonjs@6.22.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.22.0.tgz", - "dev": true - }, - "babel-plugin-transform-flow-strip-types": { - "version": "6.22.0", - "from": "babel-plugin-transform-flow-strip-types@6.22.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-flow-strip-types/-/babel-plugin-transform-flow-strip-types-6.22.0.tgz", - "dev": true - }, - "babel-plugin-transform-inline-imports-commonjs": { - "version": "1.2.0", - "from": "babel-plugin-transform-inline-imports-commonjs@1.2.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-inline-imports-commonjs/-/babel-plugin-transform-inline-imports-commonjs-1.2.0.tgz", - "dev": true - }, - "babel-plugin-transform-object-rest-spread": { - "version": "6.22.0", - "from": "babel-plugin-transform-object-rest-spread@6.22.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-object-rest-spread/-/babel-plugin-transform-object-rest-spread-6.22.0.tgz", - "dev": true - }, - "babel-plugin-transform-react-display-name": { - "version": "6.22.0", - "from": "babel-plugin-transform-react-display-name@6.22.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-react-display-name/-/babel-plugin-transform-react-display-name-6.22.0.tgz", - "dev": true - }, - "babel-plugin-transform-react-jsx": { - "version": "6.22.0", - "from": "babel-plugin-transform-react-jsx@6.22.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-react-jsx/-/babel-plugin-transform-react-jsx-6.22.0.tgz", - "dev": true - }, - "babel-plugin-transform-strict-mode": { - "version": "6.22.0", - "from": "babel-plugin-transform-strict-mode@6.22.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-strict-mode/-/babel-plugin-transform-strict-mode-6.22.0.tgz", - "dev": true - }, - "babel-polyfill": { - "version": "6.22.0", - "from": "babel-polyfill@>=6.7.2 <7.0.0", - "resolved": "https://registry.npmjs.org/babel-polyfill/-/babel-polyfill-6.22.0.tgz", - "dev": true - }, - "babel-register": { - "version": "6.22.0", - "from": "babel-register@>=6.22.0 <7.0.0", - "resolved": "https://registry.npmjs.org/babel-register/-/babel-register-6.22.0.tgz", - "dev": true - }, - "babel-runtime": { - "version": "6.22.0", - "from": "babel-runtime@>=6.22.0 <7.0.0", - "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.22.0.tgz", - "dev": true - }, - "babel-template": { - "version": "6.22.0", - "from": "babel-template@>=6.22.0 <7.0.0", - "resolved": "https://registry.npmjs.org/babel-template/-/babel-template-6.22.0.tgz", - "dev": true - }, - "babel-traverse": { - "version": "6.22.1", - "from": "babel-traverse@>=6.22.1 <7.0.0", - "resolved": "https://registry.npmjs.org/babel-traverse/-/babel-traverse-6.22.1.tgz", - "dev": true - }, - "babel-types": { - "version": "6.22.0", - "from": "babel-types@6.22.0", - "resolved": "https://registry.npmjs.org/babel-types/-/babel-types-6.22.0.tgz", - "dev": true - }, "babylon": { "version": "6.15.0", "from": "babylon@6.15.0", @@ -400,24 +133,6 @@ "from": "buffer-shims@>=1.0.0 <2.0.0", "resolved": "https://registry.npmjs.org/buffer-shims/-/buffer-shims-1.0.0.tgz" }, - "builtin-modules": { - "version": "1.1.1", - "from": "builtin-modules@>=1.1.1 <2.0.0", - "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", - "dev": true - }, - "caller-path": { - "version": "0.1.0", - "from": "caller-path@>=0.1.0 <0.2.0", - "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-0.1.0.tgz", - "dev": true - }, - "callsites": { - "version": "0.2.0", - "from": "callsites@>=0.2.0 <0.3.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-0.2.0.tgz", - "dev": true - }, "camelcase": { "version": "2.1.1", "from": "camelcase@>=2.0.1 <3.0.0", @@ -438,57 +153,21 @@ "from": "cheerio@0.22.0", "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-0.22.0.tgz" }, - "chevrotain": { - "version": "0.8.1", - "from": "chevrotain@>=0.8.0 <0.9.0", - "resolved": "https://registry.npmjs.org/chevrotain/-/chevrotain-0.8.1.tgz", - "dev": true - }, - "circular-json": { - "version": "0.3.1", - "from": "circular-json@>=0.3.1 <0.4.0", - "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.3.1.tgz", - "dev": true - }, "classnames": { "version": "2.2.5", "from": "classnames@2.2.5", "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.2.5.tgz" }, - "cli-cursor": { - "version": "1.0.2", - "from": "cli-cursor@>=1.0.1 <2.0.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-1.0.2.tgz", - "dev": true - }, - "cli-width": { - "version": "2.1.0", - "from": "cli-width@>=2.0.0 <3.0.0", - "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.1.0.tgz", - "dev": true - }, "cliui": { "version": "3.2.0", "from": "cliui@>=3.0.3 <4.0.0", "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz" }, - "co": { - "version": "4.6.0", - "from": "co@>=4.6.0 <5.0.0", - "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", - "dev": true - }, "code-point-at": { "version": "1.1.0", "from": "code-point-at@>=1.0.0 <2.0.0", "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz" }, - "coffee-script": { - "version": "1.12.3", - "from": "coffee-script@>=1.0.1", - "resolved": "https://registry.npmjs.org/coffee-script/-/coffee-script-1.12.3.tgz", - "dev": true - }, "combined-stream": { "version": "1.0.5", "from": "combined-stream@>=1.0.5 <1.1.0", @@ -499,23 +178,11 @@ "from": "commander@>=2.9.0 <3.0.0", "resolved": "https://registry.npmjs.org/commander/-/commander-2.9.0.tgz" }, - "commondir": { - "version": "1.0.1", - "from": "commondir@>=1.0.1 <2.0.0", - "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", - "dev": true - }, "concat-map": { "version": "0.0.1", "from": "concat-map@0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz" }, - "concat-stream": { - "version": "1.6.0", - "from": "concat-stream@>=1.4.6 <2.0.0", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.0.tgz", - "dev": true - }, "connect": { "version": "3.5.0", "from": "connect@3.5.0", @@ -526,12 +193,6 @@ "from": "consistent-env@>=1.2.0 <2.0.0", "resolved": "https://registry.npmjs.org/consistent-env/-/consistent-env-1.3.0.tgz" }, - "convert-source-map": { - "version": "1.3.0", - "from": "convert-source-map@>=1.1.0 <2.0.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.3.0.tgz", - "dev": true - }, "core-js": { "version": "2.4.1", "from": "core-js@2.4.1", @@ -557,18 +218,6 @@ "from": "css-what@>=2.1.0 <2.2.0", "resolved": "https://registry.npmjs.org/css-what/-/css-what-2.1.0.tgz" }, - "cubic2quad": { - "version": "1.1.0", - "from": "cubic2quad@>=1.0.0 <2.0.0", - "resolved": "https://registry.npmjs.org/cubic2quad/-/cubic2quad-1.1.0.tgz", - "dev": true - }, - "d": { - "version": "0.1.1", - "from": "d@>=0.1.1 <0.2.0", - "resolved": "https://registry.npmjs.org/d/-/d-0.1.1.tgz", - "dev": true - }, "dashdash": { "version": "1.14.1", "from": "dashdash@>=1.12.0 <2.0.0", @@ -596,18 +245,6 @@ "from": "dedent@0.6.0", "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.6.0.tgz" }, - "deep-is": { - "version": "0.1.3", - "from": "deep-is@>=0.1.3 <0.2.0", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", - "dev": true - }, - "del": { - "version": "2.2.2", - "from": "del@>=2.0.2 <3.0.0", - "resolved": "https://registry.npmjs.org/del/-/del-2.2.2.tgz", - "dev": true - }, "delayed-stream": { "version": "1.0.0", "from": "delayed-stream@>=1.0.0 <1.1.0", @@ -618,23 +255,11 @@ "from": "dequeue@1.0.5", "resolved": "https://registry.npmjs.org/dequeue/-/dequeue-1.0.5.tgz" }, - "detect-indent": { - "version": "4.0.0", - "from": "detect-indent@>=4.0.0 <5.0.0", - "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-4.0.0.tgz", - "dev": true - }, "diff": { "version": "3.0.1", "from": "diff@3.0.1", "resolved": "https://registry.npmjs.org/diff/-/diff-3.0.1.tgz" }, - "doctrine": { - "version": "1.5.0", - "from": "doctrine@>=1.2.2 <2.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz", - "dev": true - }, "dom-serializer": { "version": "0.1.0", "from": "dom-serializer@>=0.1.0 <0.2.0", @@ -683,48 +308,6 @@ "from": "entities@>=1.1.1 <1.2.0", "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.1.tgz" }, - "es5-ext": { - "version": "0.10.12", - "from": "es5-ext@>=0.10.11 <0.11.0", - "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.12.tgz", - "dev": true - }, - "es6-iterator": { - "version": "2.0.0", - "from": "es6-iterator@>=2.0.0 <3.0.0", - "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.0.tgz", - "dev": true - }, - "es6-map": { - "version": "0.1.4", - "from": "es6-map@>=0.1.3 <0.2.0", - "resolved": "https://registry.npmjs.org/es6-map/-/es6-map-0.1.4.tgz", - "dev": true - }, - "es6-promise": { - "version": "3.0.2", - "from": "es6-promise@3.0.2", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-3.0.2.tgz", - "dev": true - }, - "es6-set": { - "version": "0.1.4", - "from": "es6-set@>=0.1.3 <0.2.0", - "resolved": "https://registry.npmjs.org/es6-set/-/es6-set-0.1.4.tgz", - "dev": true - }, - "es6-symbol": { - "version": "3.1.0", - "from": "es6-symbol@>=3.1.0 <3.2.0", - "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.0.tgz", - "dev": true - }, - "es6-weak-map": { - "version": "2.0.1", - "from": "es6-weak-map@>=2.0.1 <3.0.0", - "resolved": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.1.tgz", - "dev": true - }, "escape-html": { "version": "1.0.3", "from": "escape-html@>=1.0.3 <1.1.0", @@ -735,108 +318,16 @@ "from": "escape-string-regexp@1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz" }, - "escope": { - "version": "3.6.0", - "from": "escope@>=3.6.0 <4.0.0", - "resolved": "https://registry.npmjs.org/escope/-/escope-3.6.0.tgz", - "dev": true - }, - "eslint": { - "version": "3.12.0", - "from": "eslint@3.12.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-3.12.0.tgz", - "dev": true - }, - "eslint-plugin-dependencies": { - "version": "2.2.0", - "from": "eslint-plugin-dependencies@2.2.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-dependencies/-/eslint-plugin-dependencies-2.2.0.tgz", - "dev": true - }, - "eslint-plugin-flowtype": { - "version": "2.29.1", - "from": "eslint-plugin-flowtype@2.29.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-flowtype/-/eslint-plugin-flowtype-2.29.1.tgz", - "dev": true - }, - "eslint-plugin-jasmine": { - "version": "2.2.0", - "from": "eslint-plugin-jasmine@2.2.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-jasmine/-/eslint-plugin-jasmine-2.2.0.tgz", - "dev": true - }, - "eslint-plugin-nuclide-internal": { - "version": "0.0.35", - "from": "resources/eslint-plugin-nuclide-internal", - "resolved": "file:resources/eslint-plugin-nuclide-internal", - "dev": true - }, - "eslint-plugin-prefer-object-spread": { - "version": "1.1.0", - "from": "eslint-plugin-prefer-object-spread@1.1.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-prefer-object-spread/-/eslint-plugin-prefer-object-spread-1.1.0.tgz", - "dev": true - }, - "eslint-plugin-react": { - "version": "6.8.0", - "from": "eslint-plugin-react@6.8.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-6.8.0.tgz", - "dev": true - }, - "espree": { - "version": "3.3.2", - "from": "espree@>=3.3.1 <4.0.0", - "resolved": "https://registry.npmjs.org/espree/-/espree-3.3.2.tgz", - "dev": true - }, "esprima": { "version": "2.7.3", "from": "esprima@>=2.6.0 <3.0.0", "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz" }, - "esrecurse": { - "version": "4.1.0", - "from": "esrecurse@>=4.1.0 <5.0.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.1.0.tgz", - "dev": true, - "dependencies": { - "estraverse": { - "version": "4.1.1", - "from": "estraverse@>=4.1.0 <4.2.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.1.1.tgz", - "dev": true - } - } - }, - "estraverse": { - "version": "4.2.0", - "from": "estraverse@>=4.2.0 <5.0.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz", - "dev": true - }, - "esutils": { - "version": "2.0.2", - "from": "esutils@>=2.0.2 <3.0.0", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", - "dev": true - }, - "event-emitter": { - "version": "0.3.4", - "from": "event-emitter@>=0.3.4 <0.4.0", - "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.4.tgz", - "dev": true - }, "event-kit": { "version": "2.2.0", "from": "event-kit@2.2.0", "resolved": "https://registry.npmjs.org/event-kit/-/event-kit-2.2.0.tgz" }, - "exit-hook": { - "version": "1.1.1", - "from": "exit-hook@>=1.0.0 <2.0.0", - "resolved": "https://registry.npmjs.org/exit-hook/-/exit-hook-1.1.1.tgz", - "dev": true - }, "extend": { "version": "3.0.0", "from": "extend@>=3.0.0 <3.1.0", @@ -847,12 +338,6 @@ "from": "extsprintf@1.0.2", "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.0.2.tgz" }, - "fast-levenshtein": { - "version": "2.0.6", - "from": "fast-levenshtein@>=2.0.4 <2.1.0", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "dev": true - }, "fb-watchman": { "version": "1.9.0", "from": "fb-watchman@1.9.0", @@ -870,69 +355,11 @@ } } }, - "figures": { - "version": "1.7.0", - "from": "figures@>=1.3.5 <2.0.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz", - "dev": true - }, - "file-entry-cache": { - "version": "2.0.0", - "from": "file-entry-cache@>=2.0.0 <3.0.0", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-2.0.0.tgz", - "dev": true - }, - "fileset": { - "version": "0.1.8", - "from": "fileset@>=0.1.5 <0.2.0", - "resolved": "https://registry.npmjs.org/fileset/-/fileset-0.1.8.tgz", - "dev": true, - "dependencies": { - "glob": { - "version": "3.2.11", - "from": "glob@>=3.0.0 <4.0.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-3.2.11.tgz", - "dev": true, - "dependencies": { - "minimatch": { - "version": "0.3.0", - "from": "minimatch@>=0.3.0 <0.4.0", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-0.3.0.tgz", - "dev": true - } - } - }, - "lru-cache": { - "version": "2.7.3", - "from": "lru-cache@>=2.0.0 <3.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-2.7.3.tgz", - "dev": true - }, - "minimatch": { - "version": "0.4.0", - "from": "minimatch@>=0.0.0 <1.0.0", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-0.4.0.tgz", - "dev": true - } - } - }, "finalhandler": { "version": "0.5.0", "from": "finalhandler@0.5.0", "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-0.5.0.tgz" }, - "flat-cache": { - "version": "1.2.2", - "from": "flat-cache@>=1.2.1 <2.0.0", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-1.2.2.tgz", - "dev": true - }, - "flow-bin": { - "version": "0.38.0", - "from": "flow-bin@0.38.0", - "resolved": "https://registry.npmjs.org/flow-bin/-/flow-bin-0.38.0.tgz", - "dev": true - }, "forever-agent": { "version": "0.6.1", "from": "forever-agent@>=0.6.1 <0.7.0", @@ -943,12 +370,6 @@ "from": "form-data@>=2.1.1 <2.2.0", "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.1.2.tgz" }, - "fs-extra": { - "version": "2.0.0", - "from": "fs-extra@2.0.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-2.0.0.tgz", - "dev": true - }, "fs-plus": { "version": "2.9.3", "from": "fs-plus@2.9.3", @@ -976,26 +397,6 @@ "from": "fuzzaldrin-plus@0.4.1", "resolved": "https://registry.npmjs.org/fuzzaldrin-plus/-/fuzzaldrin-plus-0.4.1.tgz" }, - "gaze": { - "version": "0.3.4", - "from": "gaze@>=0.3.2 <0.4.0", - "resolved": "https://registry.npmjs.org/gaze/-/gaze-0.3.4.tgz", - "dev": true, - "dependencies": { - "lru-cache": { - "version": "2.7.3", - "from": "lru-cache@>=2.0.0 <3.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-2.7.3.tgz", - "dev": true - }, - "minimatch": { - "version": "0.2.14", - "from": "minimatch@>=0.2.9 <0.3.0", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-0.2.14.tgz", - "dev": true - } - } - }, "generate-function": { "version": "2.0.0", "from": "generate-function@>=2.0.0 <3.0.0", @@ -1023,24 +424,6 @@ "from": "glob@7.1.1", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.1.tgz" }, - "globals": { - "version": "9.14.0", - "from": "globals@>=9.0.0 <10.0.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-9.14.0.tgz", - "dev": true - }, - "globby": { - "version": "5.0.0", - "from": "globby@>=5.0.0 <6.0.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-5.0.0.tgz", - "dev": true - }, - "graceful-fs": { - "version": "4.1.11", - "from": "graceful-fs@>=4.1.2 <5.0.0", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", - "dev": true - }, "graceful-readlink": { "version": "1.0.1", "from": "graceful-readlink@>=1.0.0", @@ -1051,18 +434,6 @@ "from": "graphql@0.7.2", "resolved": "https://registry.npmjs.org/graphql/-/graphql-0.7.2.tgz" }, - "growl": { - "version": "1.7.0", - "from": "growl@>=1.7.0 <1.8.0", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.7.0.tgz", - "dev": true - }, - "handlebars": { - "version": "2.0.0", - "from": "handlebars@>=2.0.0 <3.0.0", - "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-2.0.0.tgz", - "dev": true - }, "har-validator": { "version": "2.0.6", "from": "har-validator@>=2.0.6 <2.1.0", @@ -1088,12 +459,6 @@ "from": "hoek@>=2.0.0 <3.0.0", "resolved": "https://registry.npmjs.org/hoek/-/hoek-2.16.3.tgz" }, - "home-or-tmp": { - "version": "2.0.0", - "from": "home-or-tmp@>=2.0.0 <3.0.0", - "resolved": "https://registry.npmjs.org/home-or-tmp/-/home-or-tmp-2.0.0.tgz", - "dev": true - }, "htmlparser2": { "version": "3.9.2", "from": "htmlparser2@>=3.9.1 <4.0.0", @@ -1109,23 +474,11 @@ "from": "iconv-lite@>=0.4.13 <0.5.0", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.15.tgz" }, - "ignore": { - "version": "3.2.2", - "from": "ignore@>=3.2.0 <4.0.0", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.2.2.tgz", - "dev": true - }, "immutable": { "version": "3.7.6", "from": "immutable@3.7.6", "resolved": "https://registry.npmjs.org/immutable/-/immutable-3.7.6.tgz" }, - "imurmurhash": { - "version": "0.1.4", - "from": "imurmurhash@>=0.1.4 <0.2.0", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "dev": true - }, "inflight": { "version": "1.0.6", "from": "inflight@>=1.0.4 <2.0.0", @@ -1141,35 +494,11 @@ "from": "ini@1.3.4", "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.4.tgz" }, - "inquirer": { - "version": "0.12.0", - "from": "inquirer@>=0.12.0 <0.13.0", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-0.12.0.tgz", - "dev": true - }, - "interpret": { - "version": "1.0.1", - "from": "interpret@>=1.0.0 <2.0.0", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.0.1.tgz", - "dev": true - }, - "invariant": { - "version": "2.2.2", - "from": "invariant@>=2.2.0 <3.0.0", - "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.2.tgz", - "dev": true - }, "invert-kv": { "version": "1.0.0", "from": "invert-kv@>=1.0.0 <2.0.0", "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz" }, - "is-finite": { - "version": "1.0.2", - "from": "is-finite@>=1.0.0 <2.0.0", - "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.0.2.tgz", - "dev": true - }, "is-fullwidth-code-point": { "version": "1.0.0", "from": "is-fullwidth-code-point@>=1.0.0 <2.0.0", @@ -1180,35 +509,11 @@ "from": "is-my-json-valid@>=2.12.4 <3.0.0", "resolved": "https://registry.npmjs.org/is-my-json-valid/-/is-my-json-valid-2.15.0.tgz" }, - "is-path-cwd": { - "version": "1.0.0", - "from": "is-path-cwd@>=1.0.0 <2.0.0", - "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-1.0.0.tgz", - "dev": true - }, - "is-path-in-cwd": { - "version": "1.0.0", - "from": "is-path-in-cwd@>=1.0.0 <2.0.0", - "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-1.0.0.tgz", - "dev": true - }, - "is-path-inside": { - "version": "1.0.0", - "from": "is-path-inside@>=1.0.0 <2.0.0", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.0.tgz", - "dev": true - }, "is-property": { "version": "1.0.2", "from": "is-property@>=1.0.0 <2.0.0", "resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz" }, - "is-resolvable": { - "version": "1.0.0", - "from": "is-resolvable@>=1.0.0 <2.0.0", - "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.0.0.tgz", - "dev": true - }, "is-stream": { "version": "1.1.0", "from": "is-stream@>=1.0.1 <2.0.0", @@ -1239,40 +544,6 @@ "from": "iterall@1.0.2", "resolved": "https://registry.npmjs.org/iterall/-/iterall-1.0.2.tgz" }, - "jasmine-growl-reporter": { - "version": "0.0.3", - "from": "jasmine-growl-reporter@>=0.0.2 <0.1.0", - "resolved": "https://registry.npmjs.org/jasmine-growl-reporter/-/jasmine-growl-reporter-0.0.3.tgz", - "dev": true - }, - "jasmine-node": { - "version": "1.14.5", - "from": "jasmine-node@1.14.5", - "resolved": "https://registry.npmjs.org/jasmine-node/-/jasmine-node-1.14.5.tgz", - "dev": true, - "dependencies": { - "mkdirp": { - "version": "0.3.5", - "from": "mkdirp@>=0.3.5 <0.4.0", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.3.5.tgz", - "dev": true - } - } - }, - "jasmine-reporters": { - "version": "1.0.2", - "from": "jasmine-reporters@>=1.0.0 <1.1.0", - "resolved": "https://registry.npmjs.org/jasmine-reporters/-/jasmine-reporters-1.0.2.tgz", - "dev": true, - "dependencies": { - "mkdirp": { - "version": "0.3.5", - "from": "mkdirp@>=0.3.5 <0.4.0", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.3.5.tgz", - "dev": true - } - } - }, "jodid25519": { "version": "1.0.2", "from": "jodid25519@>=1.0.0 <2.0.0", @@ -1295,40 +566,16 @@ "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.0.tgz", "optional": true }, - "jsesc": { - "version": "1.3.0", - "from": "jsesc@>=1.3.0 <2.0.0", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-1.3.0.tgz", - "dev": true - }, "json-schema": { "version": "0.2.3", "from": "json-schema@0.2.3", "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz" }, - "json-stable-stringify": { - "version": "1.0.1", - "from": "json-stable-stringify@>=1.0.0 <2.0.0", - "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz", - "dev": true - }, "json-stringify-safe": { "version": "5.0.1", "from": "json-stringify-safe@>=5.0.1 <5.1.0", "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz" }, - "json5": { - "version": "0.5.1", - "from": "json5@>=0.5.0 <0.6.0", - "resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz", - "dev": true - }, - "jsonfile": { - "version": "2.4.0", - "from": "jsonfile@>=2.1.0 <3.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", - "dev": true - }, "jsonify": { "version": "0.0.0", "from": "jsonify@>=0.0.0 <0.1.0", @@ -1344,23 +591,11 @@ "from": "jsprim@>=1.2.2 <2.0.0", "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.3.1.tgz" }, - "jsx-ast-utils": { - "version": "1.3.5", - "from": "jsx-ast-utils@>=1.3.4 <2.0.0", - "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-1.3.5.tgz", - "dev": true - }, "lcid": { "version": "1.0.0", "from": "lcid@>=1.0.0 <2.0.0", "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz" }, - "levn": { - "version": "0.3.0", - "from": "levn@>=0.3.0 <0.4.0", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", - "dev": true - }, "lodash": { "version": "4.17.4", "from": "lodash@>=4.2.1 <5.0.0", @@ -1441,12 +676,6 @@ "from": "lodash.pick@>=4.2.1 <5.0.0", "resolved": "https://registry.npmjs.org/lodash.pick/-/lodash.pick-4.4.0.tgz" }, - "lodash.pickby": { - "version": "4.6.0", - "from": "lodash.pickby@>=4.6.0 <5.0.0", - "resolved": "https://registry.npmjs.org/lodash.pickby/-/lodash.pickby-4.6.0.tgz", - "dev": true - }, "lodash.reduce": { "version": "4.6.0", "from": "lodash.reduce@>=4.4.0 <5.0.0", @@ -1504,12 +733,6 @@ "from": "marked@0.3.6", "resolved": "https://registry.npmjs.org/marked/-/marked-0.3.6.tgz" }, - "microbuffer": { - "version": "1.0.0", - "from": "microbuffer@>=1.0.0 <2.0.0", - "resolved": "https://registry.npmjs.org/microbuffer/-/microbuffer-1.0.0.tgz", - "dev": true - }, "mime-db": { "version": "1.26.0", "from": "mime-db@>=1.26.0 <1.27.0", @@ -1535,23 +758,11 @@ "from": "mkdirp@0.5.1", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz" }, - "mock-spawn": { - "version": "0.2.6", - "from": "mock-spawn@0.2.6", - "resolved": "https://registry.npmjs.org/mock-spawn/-/mock-spawn-0.2.6.tgz", - "dev": true - }, "ms": { "version": "0.7.1", "from": "ms@0.7.1", "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz" }, - "mute-stream": { - "version": "0.0.5", - "from": "mute-stream@0.0.5", - "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.5.tgz", - "dev": true - }, "mv": { "version": "2.1.1", "from": "mv@2.1.1", @@ -1569,23 +780,11 @@ } } }, - "natural-compare": { - "version": "1.4.0", - "from": "natural-compare@>=1.4.0 <2.0.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "dev": true - }, "ncp": { "version": "2.0.0", "from": "ncp@>=2.0.0 <2.1.0", "resolved": "https://registry.npmjs.org/ncp/-/ncp-2.0.0.tgz" }, - "neatequal": { - "version": "1.0.0", - "from": "neatequal@>=1.0.0 <2.0.0", - "resolved": "https://registry.npmjs.org/neatequal/-/neatequal-1.0.0.tgz", - "dev": true - }, "node-fetch": { "version": "1.6.3", "from": "node-fetch@1.6.3", @@ -1596,12 +795,6 @@ "from": "node-int64@>=0.4.0 <0.5.0", "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz" }, - "nopt": { - "version": "1.0.10", - "from": "nopt@>=1.0.10 <1.1.0", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz", - "dev": true - }, "nth-check": { "version": "1.0.1", "from": "nth-check@>=1.0.1 <1.1.0", @@ -1637,43 +830,11 @@ "from": "once@>=1.3.0 <2.0.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz" }, - "onetime": { - "version": "1.1.0", - "from": "onetime@>=1.0.0 <2.0.0", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-1.1.0.tgz", - "dev": true - }, - "optimist": { - "version": "0.3.7", - "from": "optimist@>=0.3.0 <0.4.0", - "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.3.7.tgz", - "dev": true, - "dependencies": { - "wordwrap": { - "version": "0.0.3", - "from": "wordwrap@>=0.0.2 <0.1.0", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", - "dev": true - } - } - }, - "optionator": { - "version": "0.8.2", - "from": "optionator@>=0.8.2 <0.9.0", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz", - "dev": true - }, "options": { "version": "0.0.6", "from": "options@>=0.0.5", "resolved": "https://registry.npmjs.org/options/-/options-0.0.6.tgz" }, - "os-homedir": { - "version": "1.0.2", - "from": "os-homedir@>=1.0.0 <2.0.0", - "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", - "dev": true - }, "os-locale": { "version": "1.4.0", "from": "os-locale@>=1.4.0 <2.0.0", @@ -1684,12 +845,6 @@ "from": "os-tmpdir@>=1.0.0 <2.0.0", "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz" }, - "pako": { - "version": "1.0.4", - "from": "pako@>=1.0.0 <2.0.0", - "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.4.tgz", - "dev": true - }, "parseurl": { "version": "1.3.1", "from": "parseurl@>=1.3.1 <1.4.0", @@ -1700,18 +855,6 @@ "from": "path-is-absolute@>=1.0.0 <2.0.0", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz" }, - "path-is-inside": { - "version": "1.0.2", - "from": "path-is-inside@>=1.0.1 <2.0.0", - "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", - "dev": true - }, - "pify": { - "version": "2.3.0", - "from": "pify@>=2.0.0 <3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "dev": true - }, "pinkie": { "version": "2.0.4", "from": "pinkie@>=2.0.0 <3.0.0", @@ -1727,35 +870,11 @@ "from": "plist@2.0.1", "resolved": "https://registry.npmjs.org/plist/-/plist-2.0.1.tgz" }, - "pluralize": { - "version": "1.2.1", - "from": "pluralize@>=1.2.1 <2.0.0", - "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-1.2.1.tgz", - "dev": true - }, - "prelude-ls": { - "version": "1.1.2", - "from": "prelude-ls@>=1.1.2 <1.2.0", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", - "dev": true - }, - "private": { - "version": "0.1.6", - "from": "private@>=0.1.6 <0.2.0", - "resolved": "https://registry.npmjs.org/private/-/private-0.1.6.tgz", - "dev": true - }, "process-nextick-args": { "version": "1.0.7", "from": "process-nextick-args@>=1.0.6 <1.1.0", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz" }, - "progress": { - "version": "1.1.8", - "from": "progress@>=1.1.8 <2.0.0", - "resolved": "https://registry.npmjs.org/progress/-/progress-1.1.8.tgz", - "dev": true - }, "promise": { "version": "7.1.1", "from": "promise@>=7.1.1 <8.0.0", @@ -1771,12 +890,6 @@ "from": "punycode@>=1.4.1 <2.0.0", "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz" }, - "q": { - "version": "1.4.1", - "from": "q@>=1.1.2 <2.0.0", - "resolved": "https://registry.npmjs.org/q/-/q-1.4.1.tgz", - "dev": true - }, "qs": { "version": "6.3.0", "from": "qs@>=6.3.0 <6.4.0", @@ -1852,113 +965,31 @@ "from": "readable-stream@>=2.0.2 <3.0.0", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.2.2.tgz" }, - "readline2": { - "version": "1.0.1", - "from": "readline2@>=1.0.1 <2.0.0", - "resolved": "https://registry.npmjs.org/readline2/-/readline2-1.0.1.tgz", - "dev": true - }, - "rechoir": { - "version": "0.6.2", - "from": "rechoir@>=0.6.2 <0.7.0", - "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", - "dev": true - }, "redux": { "version": "3.6.0", "from": "redux@3.6.0", "resolved": "https://registry.npmjs.org/redux/-/redux-3.6.0.tgz" }, - "regenerator-runtime": { - "version": "0.10.1", - "from": "regenerator-runtime@>=0.10.0 <0.11.0", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.10.1.tgz", - "dev": true - }, - "repeating": { - "version": "2.0.1", - "from": "repeating@>=2.0.0 <3.0.0", - "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz", - "dev": true - }, "request": { "version": "2.79.0", "from": "request@2.79.0", "resolved": "https://registry.npmjs.org/request/-/request-2.79.0.tgz" }, - "require-uncached": { - "version": "1.0.3", - "from": "require-uncached@>=1.0.2 <2.0.0", - "resolved": "https://registry.npmjs.org/require-uncached/-/require-uncached-1.0.3.tgz", - "dev": true, - "dependencies": { - "resolve-from": { - "version": "1.0.1", - "from": "resolve-from@>=1.0.0 <2.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-1.0.1.tgz", - "dev": true - } - } - }, - "requirejs": { - "version": "2.3.2", - "from": "requirejs@>=0.27.1", - "resolved": "https://registry.npmjs.org/requirejs/-/requirejs-2.3.2.tgz", - "dev": true - }, - "resolve": { - "version": "1.2.0", - "from": "resolve@>=1.1.6 <2.0.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.2.0.tgz", - "dev": true - }, "resolve-from": { "version": "2.0.0", "from": "resolve-from@2.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-2.0.0.tgz" }, - "restore-cursor": { - "version": "1.0.1", - "from": "restore-cursor@>=1.0.1 <2.0.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-1.0.1.tgz", - "dev": true - }, "rimraf": { "version": "2.5.4", "from": "rimraf@2.5.4", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.5.4.tgz" }, - "run-async": { - "version": "0.1.0", - "from": "run-async@>=0.1.0 <0.2.0", - "resolved": "https://registry.npmjs.org/run-async/-/run-async-0.1.0.tgz", - "dev": true - }, - "rx-lite": { - "version": "3.1.2", - "from": "rx-lite@>=3.1.2 <4.0.0", - "resolved": "https://registry.npmjs.org/rx-lite/-/rx-lite-3.1.2.tgz", - "dev": true - }, "rxjs": { "version": "5.0.1", "from": "rxjs@5.0.1", "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-5.0.1.tgz" }, - "sabor": { - "version": "0.8.0", - "from": "sabor@0.8.0", - "resolved": "https://registry.npmjs.org/sabor/-/sabor-0.8.0.tgz", - "dev": true, - "dependencies": { - "resolve": { - "version": "1.1.6", - "from": "resolve@1.1.6", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.6.tgz", - "dev": true - } - } - }, "sax": { "version": "1.2.1", "from": "sax@>=0.6.0", @@ -2009,52 +1040,16 @@ "from": "shell-quote@1.6.1", "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.6.1.tgz" }, - "shelljs": { - "version": "0.7.6", - "from": "shelljs@>=0.7.5 <0.8.0", - "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.7.6.tgz", - "dev": true - }, - "sigmund": { - "version": "1.0.1", - "from": "sigmund@>=1.0.0 <1.1.0", - "resolved": "https://registry.npmjs.org/sigmund/-/sigmund-1.0.1.tgz", - "dev": true - }, "simple-text-buffer": { "version": "9.2.11", "from": "simple-text-buffer@9.2.11", "resolved": "https://registry.npmjs.org/simple-text-buffer/-/simple-text-buffer-9.2.11.tgz" }, - "slash": { - "version": "1.0.0", - "from": "slash@>=1.0.0 <2.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz", - "dev": true - }, - "slice-ansi": { - "version": "0.0.4", - "from": "slice-ansi@0.0.4", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-0.0.4.tgz", - "dev": true - }, "sntp": { "version": "1.0.9", "from": "sntp@>=1.0.0 <2.0.0", "resolved": "https://registry.npmjs.org/sntp/-/sntp-1.0.9.tgz" }, - "source-map": { - "version": "0.5.6", - "from": "source-map@>=0.5.0 <0.6.0", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.6.tgz", - "dev": true - }, - "source-map-support": { - "version": "0.4.11", - "from": "source-map-support@>=0.4.2 <0.5.0", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.4.11.tgz", - "dev": true - }, "span-skip-list": { "version": "0.2.0", "from": "span-skip-list@0.2.0", @@ -2112,18 +1107,6 @@ "from": "string-width@>=1.0.1 <2.0.0", "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz" }, - "string.fromcodepoint": { - "version": "0.2.1", - "from": "string.fromcodepoint@>=0.2.1 <0.3.0", - "resolved": "https://registry.npmjs.org/string.fromcodepoint/-/string.fromcodepoint-0.2.1.tgz", - "dev": true - }, - "string.prototype.codepointat": { - "version": "0.2.0", - "from": "string.prototype.codepointat@>=0.2.0 <0.3.0", - "resolved": "https://registry.npmjs.org/string.prototype.codepointat/-/string.prototype.codepointat-0.2.0.tgz", - "dev": true - }, "stringstream": { "version": "0.0.5", "from": "stringstream@>=0.0.4 <0.1.0", @@ -2134,80 +1117,16 @@ "from": "strip-ansi@3.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz" }, - "strip-bom": { - "version": "3.0.0", - "from": "strip-bom@>=3.0.0 <4.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "dev": true - }, - "strip-json-comments": { - "version": "1.0.4", - "from": "strip-json-comments@>=1.0.1 <1.1.0", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-1.0.4.tgz", - "dev": true - }, "supports-color": { "version": "2.0.0", "from": "supports-color@>=2.0.0 <3.0.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz" }, - "svg-pathdata": { - "version": "1.0.4", - "from": "svg-pathdata@>=1.0.3 <2.0.0", - "resolved": "https://registry.npmjs.org/svg-pathdata/-/svg-pathdata-1.0.4.tgz", - "dev": true, - "dependencies": { - "readable-stream": { - "version": "2.0.6", - "from": "readable-stream@>=2.0.4 <2.1.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.0.6.tgz", - "dev": true - } - } - }, - "svg2ttf": { - "version": "4.0.2", - "from": "svg2ttf@>=4.0.0 <5.0.0", - "resolved": "https://registry.npmjs.org/svg2ttf/-/svg2ttf-4.0.2.tgz", - "dev": true - }, - "svgicons2svgfont": { - "version": "5.0.0", - "from": "svgicons2svgfont@>=5.0.0 <6.0.0", - "resolved": "https://registry.npmjs.org/svgicons2svgfont/-/svgicons2svgfont-5.0.0.tgz", - "dev": true - }, - "svgpath": { - "version": "2.2.1", - "from": "svgpath@>=2.1.5 <3.0.0", - "resolved": "https://registry.npmjs.org/svgpath/-/svgpath-2.2.1.tgz", - "dev": true - }, "symbol-observable": { "version": "1.0.4", "from": "symbol-observable@1.0.4", "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.0.4.tgz" }, - "table": { - "version": "3.8.3", - "from": "table@>=3.7.8 <4.0.0", - "resolved": "https://registry.npmjs.org/table/-/table-3.8.3.tgz", - "dev": true, - "dependencies": { - "is-fullwidth-code-point": { - "version": "2.0.0", - "from": "is-fullwidth-code-point@>=2.0.0 <3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "dev": true - }, - "string-width": { - "version": "2.0.0", - "from": "string-width@>=2.0.0 <3.0.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.0.0.tgz", - "dev": true - } - } - }, "temp": { "version": "0.8.3", "from": "temp@0.8.3", @@ -2220,52 +1139,16 @@ } } }, - "text-table": { - "version": "0.2.0", - "from": "text-table@>=0.2.0 <0.3.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "dev": true - }, "through": { "version": "2.3.8", "from": "through@>=2.0.0 <3.0.0", "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz" }, - "to-fast-properties": { - "version": "1.0.2", - "from": "to-fast-properties@>=1.0.1 <2.0.0", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.2.tgz", - "dev": true - }, - "touch": { - "version": "1.0.0", - "from": "touch@1.0.0", - "resolved": "https://registry.npmjs.org/touch/-/touch-1.0.0.tgz", - "dev": true - }, "tough-cookie": { "version": "2.3.2", "from": "tough-cookie@>=2.3.0 <2.4.0", "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.2.tgz" }, - "tryit": { - "version": "1.0.3", - "from": "tryit@>=1.0.1 <2.0.0", - "resolved": "https://registry.npmjs.org/tryit/-/tryit-1.0.3.tgz", - "dev": true - }, - "ttf2eot": { - "version": "2.0.0", - "from": "ttf2eot@>=2.0.0 <3.0.0", - "resolved": "https://registry.npmjs.org/ttf2eot/-/ttf2eot-2.0.0.tgz", - "dev": true - }, - "ttf2woff": { - "version": "2.0.1", - "from": "ttf2woff@>=2.0.1 <3.0.0", - "resolved": "https://registry.npmjs.org/ttf2woff/-/ttf2woff-2.0.1.tgz", - "dev": true - }, "tunnel-agent": { "version": "0.4.3", "from": "tunnel-agent@>=0.4.1 <0.5.0", @@ -2277,39 +1160,11 @@ "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", "optional": true }, - "type-check": { - "version": "0.3.2", - "from": "type-check@>=0.3.2 <0.4.0", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", - "dev": true - }, - "typedarray": { - "version": "0.0.6", - "from": "typedarray@>=0.0.6 <0.0.7", - "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "dev": true - }, "ua-parser-js": { "version": "0.7.12", "from": "ua-parser-js@>=0.7.9 <0.8.0", "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.12.tgz" }, - "uglify-js": { - "version": "2.3.6", - "from": "uglify-js@>=2.3.0 <2.4.0", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.3.6.tgz", - "dev": true, - "optional": true, - "dependencies": { - "source-map": { - "version": "0.1.43", - "from": "source-map@>=0.1.7 <0.2.0", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.1.43.tgz", - "dev": true, - "optional": true - } - } - }, "ultron": { "version": "1.0.2", "from": "ultron@>=1.0.0 <1.1.0", @@ -2330,23 +1185,11 @@ "from": "unpipe@>=1.0.0 <1.1.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz" }, - "url-join": { - "version": "1.1.0", - "from": "url-join@>=1.1.0 <2.0.0", - "resolved": "https://registry.npmjs.org/url-join/-/url-join-1.1.0.tgz", - "dev": true - }, "urlregexp": { "version": "1.0.2", "from": "urlregexp@1.0.2", "resolved": "https://registry.npmjs.org/urlregexp/-/urlregexp-1.0.2.tgz" }, - "user-home": { - "version": "2.0.0", - "from": "user-home@>=2.0.0 <3.0.0", - "resolved": "https://registry.npmjs.org/user-home/-/user-home-2.0.0.tgz", - "dev": true - }, "util-deprecate": { "version": "1.0.2", "from": "util-deprecate@>=1.0.1 <1.1.0", @@ -2362,51 +1205,11 @@ "from": "uuid@3.0.1", "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.0.1.tgz" }, - "varstream": { - "version": "0.3.2", - "from": "varstream@>=0.3.2 <0.4.0", - "resolved": "https://registry.npmjs.org/varstream/-/varstream-0.3.2.tgz", - "dev": true, - "dependencies": { - "isarray": { - "version": "0.0.1", - "from": "isarray@0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "dev": true - }, - "readable-stream": { - "version": "1.1.14", - "from": "readable-stream@>=1.0.33 <2.0.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", - "dev": true - } - } - }, "verror": { "version": "1.3.6", "from": "verror@1.3.6", "resolved": "https://registry.npmjs.org/verror/-/verror-1.3.6.tgz" }, - "walkdir": { - "version": "0.0.11", - "from": "walkdir@>=0.0.1", - "resolved": "https://registry.npmjs.org/walkdir/-/walkdir-0.0.11.tgz", - "dev": true - }, - "webfonts-generator": { - "version": "0.3.5", - "from": "webfonts-generator@0.3.5", - "resolved": "https://registry.npmjs.org/webfonts-generator/-/webfonts-generator-0.3.5.tgz", - "dev": true, - "dependencies": { - "underscore": { - "version": "1.8.3", - "from": "underscore@>=1.7.0 <2.0.0", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz", - "dev": true - } - } - }, "whatwg-fetch": { "version": "2.0.2", "from": "whatwg-fetch@>=0.10.0", @@ -2417,12 +1220,6 @@ "from": "window-size@>=0.1.4 <0.2.0", "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.4.tgz" }, - "wordwrap": { - "version": "1.0.0", - "from": "wordwrap@>=1.0.0 <1.1.0", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", - "dev": true - }, "wrap-ansi": { "version": "2.1.0", "from": "wrap-ansi@>=2.0.0 <3.0.0", @@ -2433,12 +1230,6 @@ "from": "wrappy@>=1.0.0 <2.0.0", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz" }, - "write": { - "version": "0.2.1", - "from": "write@>=0.2.1 <0.3.0", - "resolved": "https://registry.npmjs.org/write/-/write-0.2.1.tgz", - "dev": true - }, "ws": { "version": "1.1.1", "from": "ws@1.1.1", diff --git a/npm-shrinkwrap.production.json b/npm-shrinkwrap.production.json deleted file mode 100644 index c771eaaeba..0000000000 --- a/npm-shrinkwrap.production.json +++ /dev/null @@ -1,1281 +0,0 @@ -{ - "name": "nuclide", - "version": "0.203.0", - "dependencies": { - "ansi-regex": { - "version": "2.1.1", - "from": "ansi-regex@>=2.0.0 <3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz" - }, - "ansi-styles": { - "version": "2.2.1", - "from": "ansi-styles@>=2.2.1 <3.0.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz" - }, - "argparse": { - "version": "1.0.9", - "from": "argparse@>=1.0.7 <2.0.0", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.9.tgz" - }, - "array-filter": { - "version": "0.0.1", - "from": "array-filter@>=0.0.0 <0.1.0", - "resolved": "https://registry.npmjs.org/array-filter/-/array-filter-0.0.1.tgz" - }, - "array-map": { - "version": "0.0.0", - "from": "array-map@>=0.0.0 <0.1.0", - "resolved": "https://registry.npmjs.org/array-map/-/array-map-0.0.0.tgz" - }, - "array-reduce": { - "version": "0.0.0", - "from": "array-reduce@>=0.0.0 <0.1.0", - "resolved": "https://registry.npmjs.org/array-reduce/-/array-reduce-0.0.0.tgz" - }, - "asap": { - "version": "2.0.5", - "from": "asap@>=2.0.3 <2.1.0", - "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.5.tgz" - }, - "asn1": { - "version": "0.2.3", - "from": "asn1@>=0.2.3 <0.3.0", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.3.tgz" - }, - "assert-plus": { - "version": "0.2.0", - "from": "assert-plus@>=0.2.0 <0.3.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.2.0.tgz" - }, - "async": { - "version": "0.2.10", - "from": "async@>=0.2.9 <0.3.0", - "resolved": "https://registry.npmjs.org/async/-/async-0.2.10.tgz" - }, - "async-to-generator": { - "version": "1.0.0", - "from": "async-to-generator@1.0.0", - "resolved": "https://registry.npmjs.org/async-to-generator/-/async-to-generator-1.0.0.tgz" - }, - "asynckit": { - "version": "0.4.0", - "from": "asynckit@>=0.4.0 <0.5.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz" - }, - "atom-package-deps": { - "version": "4.3.1", - "from": "atom-package-deps@4.3.1", - "resolved": "https://registry.npmjs.org/atom-package-deps/-/atom-package-deps-4.3.1.tgz" - }, - "atom-package-path": { - "version": "1.1.0", - "from": "atom-package-path@>=1.1.0 <2.0.0", - "resolved": "https://registry.npmjs.org/atom-package-path/-/atom-package-path-1.1.0.tgz" - }, - "atom-patch": { - "version": "0.3.0", - "from": "atom-patch@0.3.0", - "resolved": "https://registry.npmjs.org/atom-patch/-/atom-patch-0.3.0.tgz" - }, - "aws-sign2": { - "version": "0.6.0", - "from": "aws-sign2@>=0.6.0 <0.7.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.6.0.tgz" - }, - "aws4": { - "version": "1.5.0", - "from": "aws4@>=1.2.1 <2.0.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.5.0.tgz" - }, - "babylon": { - "version": "6.15.0", - "from": "babylon@6.15.0", - "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.15.0.tgz" - }, - "balanced-match": { - "version": "0.4.2", - "from": "balanced-match@>=0.4.1 <0.5.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.4.2.tgz" - }, - "base64-js": { - "version": "1.1.2", - "from": "base64-js@1.1.2", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.1.2.tgz" - }, - "bcrypt-pbkdf": { - "version": "1.0.0", - "from": "bcrypt-pbkdf@>=1.0.0 <2.0.0", - "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.0.tgz", - "optional": true - }, - "boolbase": { - "version": "1.0.0", - "from": "boolbase@>=1.0.0 <1.1.0", - "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz" - }, - "boom": { - "version": "2.10.1", - "from": "boom@>=2.0.0 <3.0.0", - "resolved": "https://registry.npmjs.org/boom/-/boom-2.10.1.tgz" - }, - "brace-expansion": { - "version": "1.1.6", - "from": "brace-expansion@>=1.0.0 <2.0.0", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.6.tgz" - }, - "bser": { - "version": "1.0.3", - "from": "bser@>=1.0.2 <2.0.0", - "resolved": "https://registry.npmjs.org/bser/-/bser-1.0.3.tgz" - }, - "buffer-shims": { - "version": "1.0.0", - "from": "buffer-shims@>=1.0.0 <2.0.0", - "resolved": "https://registry.npmjs.org/buffer-shims/-/buffer-shims-1.0.0.tgz" - }, - "camelcase": { - "version": "2.1.1", - "from": "camelcase@>=2.0.1 <3.0.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz" - }, - "caseless": { - "version": "0.11.0", - "from": "caseless@>=0.11.0 <0.12.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.11.0.tgz" - }, - "chalk": { - "version": "1.1.3", - "from": "chalk@1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz" - }, - "cheerio": { - "version": "0.22.0", - "from": "cheerio@0.22.0", - "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-0.22.0.tgz" - }, - "classnames": { - "version": "2.2.5", - "from": "classnames@2.2.5", - "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.2.5.tgz" - }, - "cliui": { - "version": "3.2.0", - "from": "cliui@>=3.0.3 <4.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz" - }, - "code-point-at": { - "version": "1.1.0", - "from": "code-point-at@>=1.0.0 <2.0.0", - "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz" - }, - "combined-stream": { - "version": "1.0.5", - "from": "combined-stream@>=1.0.5 <1.1.0", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.5.tgz" - }, - "commander": { - "version": "2.9.0", - "from": "commander@>=2.9.0 <3.0.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.9.0.tgz" - }, - "concat-map": { - "version": "0.0.1", - "from": "concat-map@0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz" - }, - "connect": { - "version": "3.5.0", - "from": "connect@3.5.0", - "resolved": "https://registry.npmjs.org/connect/-/connect-3.5.0.tgz" - }, - "consistent-env": { - "version": "1.3.0", - "from": "consistent-env@>=1.2.0 <2.0.0", - "resolved": "https://registry.npmjs.org/consistent-env/-/consistent-env-1.3.0.tgz" - }, - "core-js": { - "version": "2.4.1", - "from": "core-js@2.4.1", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.4.1.tgz" - }, - "core-util-is": { - "version": "1.0.2", - "from": "core-util-is@>=1.0.0 <1.1.0", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz" - }, - "cryptiles": { - "version": "2.0.5", - "from": "cryptiles@>=2.0.0 <3.0.0", - "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-2.0.5.tgz" - }, - "css-select": { - "version": "1.2.0", - "from": "css-select@>=1.2.0 <1.3.0", - "resolved": "https://registry.npmjs.org/css-select/-/css-select-1.2.0.tgz" - }, - "css-what": { - "version": "2.1.0", - "from": "css-what@>=2.1.0 <2.2.0", - "resolved": "https://registry.npmjs.org/css-what/-/css-what-2.1.0.tgz" - }, - "dashdash": { - "version": "1.14.1", - "from": "dashdash@>=1.12.0 <2.0.0", - "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "dependencies": { - "assert-plus": { - "version": "1.0.0", - "from": "assert-plus@>=1.0.0 <2.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz" - } - } - }, - "debug": { - "version": "2.2.0", - "from": "debug@>=2.2.0 <2.3.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz" - }, - "decamelize": { - "version": "1.2.0", - "from": "decamelize@>=1.1.1 <2.0.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz" - }, - "dedent": { - "version": "0.6.0", - "from": "dedent@0.6.0", - "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.6.0.tgz" - }, - "delayed-stream": { - "version": "1.0.0", - "from": "delayed-stream@>=1.0.0 <1.1.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz" - }, - "dequeue": { - "version": "1.0.5", - "from": "dequeue@1.0.5", - "resolved": "https://registry.npmjs.org/dequeue/-/dequeue-1.0.5.tgz" - }, - "diff": { - "version": "3.0.1", - "from": "diff@3.0.1", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.0.1.tgz" - }, - "dom-serializer": { - "version": "0.1.0", - "from": "dom-serializer@>=0.1.0 <0.2.0", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.1.0.tgz", - "dependencies": { - "domelementtype": { - "version": "1.1.3", - "from": "domelementtype@>=1.1.1 <1.2.0", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.1.3.tgz" - } - } - }, - "domelementtype": { - "version": "1.3.0", - "from": "domelementtype@>=1.0.0 <2.0.0", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.0.tgz" - }, - "domhandler": { - "version": "2.3.0", - "from": "domhandler@>=2.3.0 <3.0.0", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.3.0.tgz" - }, - "domutils": { - "version": "1.5.1", - "from": "domutils@1.5.1", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.5.1.tgz" - }, - "ecc-jsbn": { - "version": "0.1.1", - "from": "ecc-jsbn@>=0.1.1 <0.2.0", - "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz", - "optional": true - }, - "ee-first": { - "version": "1.1.1", - "from": "ee-first@1.1.1", - "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz" - }, - "encoding": { - "version": "0.1.12", - "from": "encoding@>=0.1.11 <0.2.0", - "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.12.tgz" - }, - "entities": { - "version": "1.1.1", - "from": "entities@>=1.1.1 <1.2.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.1.tgz" - }, - "escape-html": { - "version": "1.0.3", - "from": "escape-html@>=1.0.3 <1.1.0", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz" - }, - "escape-string-regexp": { - "version": "1.0.5", - "from": "escape-string-regexp@1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz" - }, - "esprima": { - "version": "2.7.3", - "from": "esprima@>=2.6.0 <3.0.0", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz" - }, - "event-kit": { - "version": "2.2.0", - "from": "event-kit@2.2.0", - "resolved": "https://registry.npmjs.org/event-kit/-/event-kit-2.2.0.tgz" - }, - "extend": { - "version": "3.0.0", - "from": "extend@>=3.0.0 <3.1.0", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.0.tgz" - }, - "extsprintf": { - "version": "1.0.2", - "from": "extsprintf@1.0.2", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.0.2.tgz" - }, - "fb-watchman": { - "version": "1.9.0", - "from": "fb-watchman@1.9.0", - "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-1.9.0.tgz" - }, - "fbjs": { - "version": "0.8.8", - "from": "fbjs@>=0.8.4 <0.9.0", - "resolved": "https://registry.npmjs.org/fbjs/-/fbjs-0.8.8.tgz", - "dependencies": { - "core-js": { - "version": "1.2.7", - "from": "core-js@>=1.0.0 <2.0.0", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-1.2.7.tgz" - } - } - }, - "finalhandler": { - "version": "0.5.0", - "from": "finalhandler@0.5.0", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-0.5.0.tgz" - }, - "forever-agent": { - "version": "0.6.1", - "from": "forever-agent@>=0.6.1 <0.7.0", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz" - }, - "form-data": { - "version": "2.1.2", - "from": "form-data@>=2.1.1 <2.2.0", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.1.2.tgz" - }, - "fs-plus": { - "version": "2.9.3", - "from": "fs-plus@2.9.3", - "resolved": "https://registry.npmjs.org/fs-plus/-/fs-plus-2.9.3.tgz", - "dependencies": { - "mkdirp": { - "version": "0.3.5", - "from": "mkdirp@>=0.3.5 <0.4.0", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.3.5.tgz" - }, - "rimraf": { - "version": "2.2.8", - "from": "rimraf@>=2.2.2 <2.3.0", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.2.8.tgz" - } - } - }, - "fs.realpath": { - "version": "1.0.0", - "from": "fs.realpath@>=1.0.0 <2.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz" - }, - "fuzzaldrin-plus": { - "version": "0.4.1", - "from": "fuzzaldrin-plus@0.4.1", - "resolved": "https://registry.npmjs.org/fuzzaldrin-plus/-/fuzzaldrin-plus-0.4.1.tgz" - }, - "generate-function": { - "version": "2.0.0", - "from": "generate-function@>=2.0.0 <3.0.0", - "resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.0.0.tgz" - }, - "generate-object-property": { - "version": "1.2.0", - "from": "generate-object-property@>=1.1.0 <2.0.0", - "resolved": "https://registry.npmjs.org/generate-object-property/-/generate-object-property-1.2.0.tgz" - }, - "getpass": { - "version": "0.1.6", - "from": "getpass@>=0.1.1 <0.2.0", - "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.6.tgz", - "dependencies": { - "assert-plus": { - "version": "1.0.0", - "from": "assert-plus@>=1.0.0 <2.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz" - } - } - }, - "glob": { - "version": "7.1.1", - "from": "glob@7.1.1", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.1.tgz" - }, - "graceful-readlink": { - "version": "1.0.1", - "from": "graceful-readlink@>=1.0.0", - "resolved": "https://registry.npmjs.org/graceful-readlink/-/graceful-readlink-1.0.1.tgz" - }, - "graphql": { - "version": "0.7.2", - "from": "graphql@0.7.2", - "resolved": "https://registry.npmjs.org/graphql/-/graphql-0.7.2.tgz" - }, - "har-validator": { - "version": "2.0.6", - "from": "har-validator@>=2.0.6 <2.1.0", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-2.0.6.tgz" - }, - "has-ansi": { - "version": "2.0.0", - "from": "has-ansi@>=2.0.0 <3.0.0", - "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz" - }, - "hawk": { - "version": "3.1.3", - "from": "hawk@>=3.1.3 <3.2.0", - "resolved": "https://registry.npmjs.org/hawk/-/hawk-3.1.3.tgz" - }, - "heap": { - "version": "0.2.6", - "from": "heap@0.2.6", - "resolved": "https://registry.npmjs.org/heap/-/heap-0.2.6.tgz" - }, - "hoek": { - "version": "2.16.3", - "from": "hoek@>=2.0.0 <3.0.0", - "resolved": "https://registry.npmjs.org/hoek/-/hoek-2.16.3.tgz" - }, - "htmlparser2": { - "version": "3.9.2", - "from": "htmlparser2@>=3.9.1 <4.0.0", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.9.2.tgz" - }, - "http-signature": { - "version": "1.1.1", - "from": "http-signature@>=1.1.0 <1.2.0", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.1.1.tgz" - }, - "iconv-lite": { - "version": "0.4.15", - "from": "iconv-lite@>=0.4.13 <0.5.0", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.15.tgz" - }, - "immutable": { - "version": "3.7.6", - "from": "immutable@3.7.6", - "resolved": "https://registry.npmjs.org/immutable/-/immutable-3.7.6.tgz" - }, - "inflight": { - "version": "1.0.6", - "from": "inflight@>=1.0.4 <2.0.0", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz" - }, - "inherits": { - "version": "2.0.3", - "from": "inherits@>=2.0.1 <3.0.0", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz" - }, - "ini": { - "version": "1.3.4", - "from": "ini@1.3.4", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.4.tgz" - }, - "invert-kv": { - "version": "1.0.0", - "from": "invert-kv@>=1.0.0 <2.0.0", - "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz" - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "from": "is-fullwidth-code-point@>=1.0.0 <2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz" - }, - "is-my-json-valid": { - "version": "2.15.0", - "from": "is-my-json-valid@>=2.12.4 <3.0.0", - "resolved": "https://registry.npmjs.org/is-my-json-valid/-/is-my-json-valid-2.15.0.tgz" - }, - "is-property": { - "version": "1.0.2", - "from": "is-property@>=1.0.0 <2.0.0", - "resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz" - }, - "is-stream": { - "version": "1.1.0", - "from": "is-stream@>=1.0.1 <2.0.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz" - }, - "is-typedarray": { - "version": "1.0.0", - "from": "is-typedarray@>=1.0.0 <1.1.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz" - }, - "isarray": { - "version": "1.0.0", - "from": "isarray@>=1.0.0 <1.1.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz" - }, - "isomorphic-fetch": { - "version": "2.2.1", - "from": "isomorphic-fetch@>=2.1.1 <3.0.0", - "resolved": "https://registry.npmjs.org/isomorphic-fetch/-/isomorphic-fetch-2.2.1.tgz" - }, - "isstream": { - "version": "0.1.2", - "from": "isstream@>=0.1.2 <0.2.0", - "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz" - }, - "iterall": { - "version": "1.0.2", - "from": "iterall@1.0.2", - "resolved": "https://registry.npmjs.org/iterall/-/iterall-1.0.2.tgz" - }, - "jodid25519": { - "version": "1.0.2", - "from": "jodid25519@>=1.0.0 <2.0.0", - "resolved": "https://registry.npmjs.org/jodid25519/-/jodid25519-1.0.2.tgz", - "optional": true - }, - "js-tokens": { - "version": "3.0.0", - "from": "js-tokens@>=3.0.0 <4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.0.tgz" - }, - "js-yaml": { - "version": "3.7.0", - "from": "js-yaml@3.7.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.7.0.tgz" - }, - "jsbn": { - "version": "0.1.0", - "from": "jsbn@>=0.1.0 <0.2.0", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.0.tgz", - "optional": true - }, - "json-schema": { - "version": "0.2.3", - "from": "json-schema@0.2.3", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz" - }, - "json-stringify-safe": { - "version": "5.0.1", - "from": "json-stringify-safe@>=5.0.1 <5.1.0", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz" - }, - "jsonify": { - "version": "0.0.0", - "from": "jsonify@>=0.0.0 <0.1.0", - "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz" - }, - "jsonpointer": { - "version": "4.0.1", - "from": "jsonpointer@>=4.0.0 <5.0.0", - "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-4.0.1.tgz" - }, - "jsprim": { - "version": "1.3.1", - "from": "jsprim@>=1.2.2 <2.0.0", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.3.1.tgz" - }, - "lcid": { - "version": "1.0.0", - "from": "lcid@>=1.0.0 <2.0.0", - "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz" - }, - "lodash": { - "version": "4.17.4", - "from": "lodash@>=4.2.1 <5.0.0", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz" - }, - "lodash-es": { - "version": "4.17.4", - "from": "lodash-es@>=4.2.1 <5.0.0", - "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.4.tgz" - }, - "lodash._getnative": { - "version": "3.9.1", - "from": "lodash._getnative@>=3.0.0 <4.0.0", - "resolved": "https://registry.npmjs.org/lodash._getnative/-/lodash._getnative-3.9.1.tgz" - }, - "lodash.assignin": { - "version": "4.2.0", - "from": "lodash.assignin@>=4.0.9 <5.0.0", - "resolved": "https://registry.npmjs.org/lodash.assignin/-/lodash.assignin-4.2.0.tgz" - }, - "lodash.bind": { - "version": "4.2.1", - "from": "lodash.bind@>=4.1.4 <5.0.0", - "resolved": "https://registry.npmjs.org/lodash.bind/-/lodash.bind-4.2.1.tgz" - }, - "lodash.defaults": { - "version": "4.2.0", - "from": "lodash.defaults@>=4.0.1 <5.0.0", - "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz" - }, - "lodash.filter": { - "version": "4.6.0", - "from": "lodash.filter@>=4.4.0 <5.0.0", - "resolved": "https://registry.npmjs.org/lodash.filter/-/lodash.filter-4.6.0.tgz" - }, - "lodash.flatten": { - "version": "4.4.0", - "from": "lodash.flatten@>=4.2.0 <5.0.0", - "resolved": "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-4.4.0.tgz" - }, - "lodash.foreach": { - "version": "4.5.0", - "from": "lodash.foreach@>=4.3.0 <5.0.0", - "resolved": "https://registry.npmjs.org/lodash.foreach/-/lodash.foreach-4.5.0.tgz" - }, - "lodash.isarguments": { - "version": "3.1.0", - "from": "lodash.isarguments@>=3.0.0 <4.0.0", - "resolved": "https://registry.npmjs.org/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz" - }, - "lodash.isarray": { - "version": "3.0.4", - "from": "lodash.isarray@>=3.0.0 <4.0.0", - "resolved": "https://registry.npmjs.org/lodash.isarray/-/lodash.isarray-3.0.4.tgz" - }, - "lodash.keys": { - "version": "3.1.2", - "from": "lodash.keys@>=3.1.2 <4.0.0", - "resolved": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-3.1.2.tgz" - }, - "lodash.map": { - "version": "4.6.0", - "from": "lodash.map@>=4.4.0 <5.0.0", - "resolved": "https://registry.npmjs.org/lodash.map/-/lodash.map-4.6.0.tgz" - }, - "lodash.memoize": { - "version": "3.0.4", - "from": "lodash.memoize@3.0.4", - "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-3.0.4.tgz" - }, - "lodash.merge": { - "version": "4.6.0", - "from": "lodash.merge@>=4.4.0 <5.0.0", - "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.0.tgz" - }, - "lodash.pick": { - "version": "4.4.0", - "from": "lodash.pick@>=4.2.1 <5.0.0", - "resolved": "https://registry.npmjs.org/lodash.pick/-/lodash.pick-4.4.0.tgz" - }, - "lodash.reduce": { - "version": "4.6.0", - "from": "lodash.reduce@>=4.4.0 <5.0.0", - "resolved": "https://registry.npmjs.org/lodash.reduce/-/lodash.reduce-4.6.0.tgz" - }, - "lodash.reject": { - "version": "4.6.0", - "from": "lodash.reject@>=4.4.0 <5.0.0", - "resolved": "https://registry.npmjs.org/lodash.reject/-/lodash.reject-4.6.0.tgz" - }, - "lodash.some": { - "version": "4.6.0", - "from": "lodash.some@>=4.4.0 <5.0.0", - "resolved": "https://registry.npmjs.org/lodash.some/-/lodash.some-4.6.0.tgz" - }, - "lodash.uniq": { - "version": "4.5.0", - "from": "lodash.uniq@>=4.5.0 <5.0.0", - "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz" - }, - "log4js": { - "version": "0.6.38", - "from": "log4js@0.6.38", - "resolved": "https://registry.npmjs.org/log4js/-/log4js-0.6.38.tgz", - "dependencies": { - "isarray": { - "version": "0.0.1", - "from": "isarray@0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz" - }, - "readable-stream": { - "version": "1.0.34", - "from": "readable-stream@>=1.0.2 <1.1.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz" - }, - "semver": { - "version": "4.3.6", - "from": "semver@>=4.3.3 <4.4.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-4.3.6.tgz" - } - } - }, - "loose-envify": { - "version": "1.3.1", - "from": "loose-envify@>=1.1.0 <2.0.0", - "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.3.1.tgz" - }, - "lru-cache": { - "version": "4.0.2", - "from": "lru-cache@4.0.2", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.0.2.tgz" - }, - "marked": { - "version": "0.3.6", - "from": "marked@0.3.6", - "resolved": "https://registry.npmjs.org/marked/-/marked-0.3.6.tgz" - }, - "mime-db": { - "version": "1.26.0", - "from": "mime-db@>=1.26.0 <1.27.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.26.0.tgz" - }, - "mime-types": { - "version": "2.1.14", - "from": "mime-types@>=2.1.7 <2.2.0", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.14.tgz" - }, - "minimatch": { - "version": "3.0.3", - "from": "minimatch@3.0.3", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.3.tgz" - }, - "minimist": { - "version": "0.0.8", - "from": "minimist@0.0.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz" - }, - "mkdirp": { - "version": "0.5.1", - "from": "mkdirp@0.5.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz" - }, - "ms": { - "version": "0.7.1", - "from": "ms@0.7.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz" - }, - "mv": { - "version": "2.1.1", - "from": "mv@2.1.1", - "resolved": "https://registry.npmjs.org/mv/-/mv-2.1.1.tgz", - "dependencies": { - "glob": { - "version": "6.0.4", - "from": "glob@>=6.0.1 <7.0.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-6.0.4.tgz" - }, - "rimraf": { - "version": "2.4.5", - "from": "rimraf@>=2.4.0 <2.5.0", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.4.5.tgz" - } - } - }, - "ncp": { - "version": "2.0.0", - "from": "ncp@>=2.0.0 <2.1.0", - "resolved": "https://registry.npmjs.org/ncp/-/ncp-2.0.0.tgz" - }, - "node-fetch": { - "version": "1.6.3", - "from": "node-fetch@1.6.3", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-1.6.3.tgz" - }, - "node-int64": { - "version": "0.4.0", - "from": "node-int64@>=0.4.0 <0.5.0", - "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz" - }, - "nth-check": { - "version": "1.0.1", - "from": "nth-check@>=1.0.1 <1.1.0", - "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-1.0.1.tgz" - }, - "nullthrows": { - "version": "1.0.0", - "from": "nullthrows@1.0.0", - "resolved": "https://registry.npmjs.org/nullthrows/-/nullthrows-1.0.0.tgz" - }, - "number-is-nan": { - "version": "1.0.1", - "from": "number-is-nan@>=1.0.0 <2.0.0", - "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz" - }, - "oauth-sign": { - "version": "0.8.2", - "from": "oauth-sign@>=0.8.1 <0.9.0", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz" - }, - "object-assign": { - "version": "4.1.1", - "from": "object-assign@>=4.1.0 <5.0.0", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz" - }, - "on-finished": { - "version": "2.3.0", - "from": "on-finished@>=2.3.0 <2.4.0", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz" - }, - "once": { - "version": "1.4.0", - "from": "once@>=1.3.0 <2.0.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz" - }, - "options": { - "version": "0.0.6", - "from": "options@>=0.0.5", - "resolved": "https://registry.npmjs.org/options/-/options-0.0.6.tgz" - }, - "os-locale": { - "version": "1.4.0", - "from": "os-locale@>=1.4.0 <2.0.0", - "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz" - }, - "os-tmpdir": { - "version": "1.0.2", - "from": "os-tmpdir@>=1.0.0 <2.0.0", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz" - }, - "parseurl": { - "version": "1.3.1", - "from": "parseurl@>=1.3.1 <1.4.0", - "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.1.tgz" - }, - "path-is-absolute": { - "version": "1.0.1", - "from": "path-is-absolute@>=1.0.0 <2.0.0", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz" - }, - "pinkie": { - "version": "2.0.4", - "from": "pinkie@>=2.0.0 <3.0.0", - "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz" - }, - "pinkie-promise": { - "version": "2.0.1", - "from": "pinkie-promise@>=2.0.0 <3.0.0", - "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz" - }, - "plist": { - "version": "2.0.1", - "from": "plist@2.0.1", - "resolved": "https://registry.npmjs.org/plist/-/plist-2.0.1.tgz" - }, - "process-nextick-args": { - "version": "1.0.7", - "from": "process-nextick-args@>=1.0.6 <1.1.0", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz" - }, - "promise": { - "version": "7.1.1", - "from": "promise@>=7.1.1 <8.0.0", - "resolved": "https://registry.npmjs.org/promise/-/promise-7.1.1.tgz" - }, - "pseudomap": { - "version": "1.0.2", - "from": "pseudomap@>=1.0.1 <2.0.0", - "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz" - }, - "punycode": { - "version": "1.4.1", - "from": "punycode@>=1.4.1 <2.0.0", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz" - }, - "qs": { - "version": "6.3.0", - "from": "qs@>=6.3.0 <6.4.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.3.0.tgz" - }, - "random-seed": { - "version": "0.2.0", - "from": "random-seed@>=0.2.0 <0.3.0", - "resolved": "https://registry.npmjs.org/random-seed/-/random-seed-0.2.0.tgz" - }, - "react": { - "version": "15.3.1", - "from": "react@15.3.1", - "resolved": "https://registry.npmjs.org/react/-/react-15.3.1.tgz" - }, - "react-addons-create-fragment": { - "version": "15.3.1", - "from": "react-addons-create-fragment@15.3.1", - "resolved": "https://registry.npmjs.org/react-addons-create-fragment/-/react-addons-create-fragment-15.3.1.tgz" - }, - "react-addons-css-transition-group": { - "version": "15.3.1", - "from": "react-addons-css-transition-group@15.3.1", - "resolved": "https://registry.npmjs.org/react-addons-css-transition-group/-/react-addons-css-transition-group-15.3.1.tgz" - }, - "react-addons-linked-state-mixin": { - "version": "15.3.1", - "from": "react-addons-linked-state-mixin@15.3.1", - "resolved": "https://registry.npmjs.org/react-addons-linked-state-mixin/-/react-addons-linked-state-mixin-15.3.1.tgz" - }, - "react-addons-perf": { - "version": "15.3.1", - "from": "react-addons-perf@15.3.1", - "resolved": "https://registry.npmjs.org/react-addons-perf/-/react-addons-perf-15.3.1.tgz" - }, - "react-addons-pure-render-mixin": { - "version": "15.3.1", - "from": "react-addons-pure-render-mixin@15.3.1", - "resolved": "https://registry.npmjs.org/react-addons-pure-render-mixin/-/react-addons-pure-render-mixin-15.3.1.tgz" - }, - "react-addons-shallow-compare": { - "version": "15.3.1", - "from": "react-addons-shallow-compare@15.3.1", - "resolved": "https://registry.npmjs.org/react-addons-shallow-compare/-/react-addons-shallow-compare-15.3.1.tgz" - }, - "react-addons-test-utils": { - "version": "15.3.1", - "from": "react-addons-test-utils@15.3.1", - "resolved": "https://registry.npmjs.org/react-addons-test-utils/-/react-addons-test-utils-15.3.1.tgz" - }, - "react-addons-transition-group": { - "version": "15.3.1", - "from": "react-addons-transition-group@15.3.1", - "resolved": "https://registry.npmjs.org/react-addons-transition-group/-/react-addons-transition-group-15.3.1.tgz" - }, - "react-addons-update": { - "version": "15.3.1", - "from": "react-addons-update@15.3.1", - "resolved": "https://registry.npmjs.org/react-addons-update/-/react-addons-update-15.3.1.tgz" - }, - "react-dom": { - "version": "15.3.1", - "from": "react-dom@15.3.1", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-15.3.1.tgz" - }, - "react-for-atom": { - "version": "15.3.1-0", - "from": "react-for-atom@15.3.1-0", - "resolved": "https://registry.npmjs.org/react-for-atom/-/react-for-atom-15.3.1-0.tgz" - }, - "readable-stream": { - "version": "2.2.2", - "from": "readable-stream@>=2.0.2 <3.0.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.2.2.tgz" - }, - "redux": { - "version": "3.6.0", - "from": "redux@3.6.0", - "resolved": "https://registry.npmjs.org/redux/-/redux-3.6.0.tgz" - }, - "request": { - "version": "2.79.0", - "from": "request@2.79.0", - "resolved": "https://registry.npmjs.org/request/-/request-2.79.0.tgz" - }, - "resolve-from": { - "version": "2.0.0", - "from": "resolve-from@2.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-2.0.0.tgz" - }, - "rimraf": { - "version": "2.5.4", - "from": "rimraf@2.5.4", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.5.4.tgz" - }, - "rxjs": { - "version": "5.0.1", - "from": "rxjs@5.0.1", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-5.0.1.tgz" - }, - "sax": { - "version": "1.2.1", - "from": "sax@>=0.6.0", - "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.1.tgz" - }, - "sb-callsite": { - "version": "1.1.2", - "from": "sb-callsite@>=1.1.2 <2.0.0", - "resolved": "https://registry.npmjs.org/sb-callsite/-/sb-callsite-1.1.2.tgz" - }, - "sb-exec": { - "version": "3.1.0", - "from": "sb-exec@>=3.0.1 <4.0.0", - "resolved": "https://registry.npmjs.org/sb-exec/-/sb-exec-3.1.0.tgz" - }, - "sb-memoize": { - "version": "1.0.2", - "from": "sb-memoize@>=1.0.2 <2.0.0", - "resolved": "https://registry.npmjs.org/sb-memoize/-/sb-memoize-1.0.2.tgz" - }, - "sb-npm-path": { - "version": "2.0.0", - "from": "sb-npm-path@>=2.0.0 <3.0.0", - "resolved": "https://registry.npmjs.org/sb-npm-path/-/sb-npm-path-2.0.0.tgz" - }, - "sb-promisify": { - "version": "2.0.1", - "from": "sb-promisify@>=2.0.1 <3.0.0", - "resolved": "https://registry.npmjs.org/sb-promisify/-/sb-promisify-2.0.1.tgz" - }, - "semver": { - "version": "5.3.0", - "from": "semver@5.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz" - }, - "setimmediate": { - "version": "1.0.5", - "from": "setimmediate@>=1.0.5 <2.0.0", - "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz" - }, - "shallowequal": { - "version": "0.2.2", - "from": "shallowequal@0.2.2", - "resolved": "https://registry.npmjs.org/shallowequal/-/shallowequal-0.2.2.tgz" - }, - "shell-quote": { - "version": "1.6.1", - "from": "shell-quote@1.6.1", - "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.6.1.tgz" - }, - "simple-text-buffer": { - "version": "9.2.11", - "from": "simple-text-buffer@9.2.11", - "resolved": "https://registry.npmjs.org/simple-text-buffer/-/simple-text-buffer-9.2.11.tgz" - }, - "sntp": { - "version": "1.0.9", - "from": "sntp@>=1.0.0 <2.0.0", - "resolved": "https://registry.npmjs.org/sntp/-/sntp-1.0.9.tgz" - }, - "span-skip-list": { - "version": "0.2.0", - "from": "span-skip-list@0.2.0", - "resolved": "https://registry.npmjs.org/span-skip-list/-/span-skip-list-0.2.0.tgz" - }, - "split": { - "version": "1.0.0", - "from": "split@1.0.0", - "resolved": "https://registry.npmjs.org/split/-/split-1.0.0.tgz" - }, - "sprintf-js": { - "version": "1.0.3", - "from": "sprintf-js@>=1.0.2 <1.1.0", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz" - }, - "ssh2": { - "version": "0.5.4", - "from": "ssh2@0.5.4", - "resolved": "https://registry.npmjs.org/ssh2/-/ssh2-0.5.4.tgz" - }, - "ssh2-streams": { - "version": "0.1.16", - "from": "ssh2-streams@>=0.1.15 <0.2.0", - "resolved": "https://registry.npmjs.org/ssh2-streams/-/ssh2-streams-0.1.16.tgz" - }, - "sshpk": { - "version": "1.10.2", - "from": "sshpk@>=1.7.0 <2.0.0", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.10.2.tgz", - "dependencies": { - "assert-plus": { - "version": "1.0.0", - "from": "assert-plus@>=1.0.0 <2.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz" - } - } - }, - "statuses": { - "version": "1.3.1", - "from": "statuses@>=1.3.0 <1.4.0", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.3.1.tgz" - }, - "streamsearch": { - "version": "0.1.2", - "from": "streamsearch@>=0.1.2 <0.2.0", - "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-0.1.2.tgz" - }, - "string_decoder": { - "version": "0.10.31", - "from": "string_decoder@>=0.10.0 <0.11.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz" - }, - "string-width": { - "version": "1.0.2", - "from": "string-width@>=1.0.1 <2.0.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz" - }, - "stringstream": { - "version": "0.0.5", - "from": "stringstream@>=0.0.4 <0.1.0", - "resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.5.tgz" - }, - "strip-ansi": { - "version": "3.0.1", - "from": "strip-ansi@3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz" - }, - "supports-color": { - "version": "2.0.0", - "from": "supports-color@>=2.0.0 <3.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz" - }, - "symbol-observable": { - "version": "1.0.4", - "from": "symbol-observable@1.0.4", - "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.0.4.tgz" - }, - "temp": { - "version": "0.8.3", - "from": "temp@0.8.3", - "resolved": "https://registry.npmjs.org/temp/-/temp-0.8.3.tgz", - "dependencies": { - "rimraf": { - "version": "2.2.8", - "from": "rimraf@>=2.2.6 <2.3.0", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.2.8.tgz" - } - } - }, - "through": { - "version": "2.3.8", - "from": "through@>=2.0.0 <3.0.0", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz" - }, - "tough-cookie": { - "version": "2.3.2", - "from": "tough-cookie@>=2.3.0 <2.4.0", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.2.tgz" - }, - "tunnel-agent": { - "version": "0.4.3", - "from": "tunnel-agent@>=0.4.1 <0.5.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.4.3.tgz" - }, - "tweetnacl": { - "version": "0.14.5", - "from": "tweetnacl@>=0.14.0 <0.15.0", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "optional": true - }, - "ua-parser-js": { - "version": "0.7.12", - "from": "ua-parser-js@>=0.7.9 <0.8.0", - "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.12.tgz" - }, - "ultron": { - "version": "1.0.2", - "from": "ultron@>=1.0.0 <1.1.0", - "resolved": "https://registry.npmjs.org/ultron/-/ultron-1.0.2.tgz" - }, - "underscore": { - "version": "1.6.0", - "from": "underscore@>=1.6.0 <1.7.0", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.6.0.tgz" - }, - "underscore-plus": { - "version": "1.6.6", - "from": "underscore-plus@>=1.0.0 <2.0.0", - "resolved": "https://registry.npmjs.org/underscore-plus/-/underscore-plus-1.6.6.tgz" - }, - "unpipe": { - "version": "1.0.0", - "from": "unpipe@>=1.0.0 <1.1.0", - "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz" - }, - "urlregexp": { - "version": "1.0.2", - "from": "urlregexp@1.0.2", - "resolved": "https://registry.npmjs.org/urlregexp/-/urlregexp-1.0.2.tgz" - }, - "util-deprecate": { - "version": "1.0.2", - "from": "util-deprecate@>=1.0.1 <1.1.0", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz" - }, - "utils-merge": { - "version": "1.0.0", - "from": "utils-merge@1.0.0", - "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.0.tgz" - }, - "uuid": { - "version": "3.0.1", - "from": "uuid@3.0.1", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.0.1.tgz" - }, - "verror": { - "version": "1.3.6", - "from": "verror@1.3.6", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.3.6.tgz" - }, - "whatwg-fetch": { - "version": "2.0.2", - "from": "whatwg-fetch@>=0.10.0", - "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-2.0.2.tgz" - }, - "window-size": { - "version": "0.1.4", - "from": "window-size@>=0.1.4 <0.2.0", - "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.4.tgz" - }, - "wrap-ansi": { - "version": "2.1.0", - "from": "wrap-ansi@>=2.0.0 <3.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz" - }, - "wrappy": { - "version": "1.0.2", - "from": "wrappy@>=1.0.0 <2.0.0", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz" - }, - "ws": { - "version": "1.1.1", - "from": "ws@1.1.1", - "resolved": "https://registry.npmjs.org/ws/-/ws-1.1.1.tgz" - }, - "xml2js": { - "version": "0.4.17", - "from": "xml2js@0.4.17", - "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.17.tgz", - "dependencies": { - "xmlbuilder": { - "version": "4.2.1", - "from": "xmlbuilder@>=4.1.0 <5.0.0", - "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-4.2.1.tgz" - } - } - }, - "xmlbuilder": { - "version": "8.2.2", - "from": "xmlbuilder@8.2.2", - "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-8.2.2.tgz" - }, - "xmldom": { - "version": "0.1.27", - "from": "xmldom@>=0.1.0 <0.2.0", - "resolved": "https://registry.npmjs.org/xmldom/-/xmldom-0.1.27.tgz" - }, - "xtend": { - "version": "4.0.1", - "from": "xtend@>=4.0.0 <5.0.0", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz" - }, - "y18n": { - "version": "3.2.1", - "from": "y18n@>=3.2.0 <4.0.0", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz" - }, - "yallist": { - "version": "2.0.0", - "from": "yallist@>=2.0.0 <3.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.0.0.tgz" - }, - "yargs": { - "version": "3.32.0", - "from": "yargs@3.32.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.32.0.tgz" - } - } -} diff --git a/package.json b/package.json index 691bb1d94c..f8688bdfd7 100644 --- a/package.json +++ b/package.json @@ -128,7 +128,6 @@ "atom": ">=1.13.0", "node": ">=6.5.0" }, - "private": true, "atomTestRunner": "./lib/test-runner-entry.js", "package-deps": [ "tool-bar", diff --git a/pkg/commons-atom/ActiveEditorRegistry.js b/pkg/commons-atom/ActiveEditorRegistry.js index 6f59b3b680..449f6afa55 100644 --- a/pkg/commons-atom/ActiveEditorRegistry.js +++ b/pkg/commons-atom/ActiveEditorRegistry.js @@ -1,3 +1,47 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _asyncToGenerator = _interopRequireDefault(require('async-to-generator')); + +var _atom = require('atom'); + +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js'); + +var _debounced; + +function _load_debounced() { + return _debounced = require('./debounced'); +} + +var _event; + +function _load_event() { + return _event = require('../commons-node/event'); +} + +var _observable; + +function _load_observable() { + return _observable = require('../commons-node/observable'); +} + +var _nuclideLogging; + +function _load_nuclideLogging() { + return _nuclideLogging = require('../nuclide-logging'); +} + +var _ProviderRegistry; + +function _load_ProviderRegistry() { + return _ProviderRegistry = _interopRequireDefault(require('./ProviderRegistry')); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,7 +49,7 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * */ /** @@ -13,163 +57,67 @@ * on text editor contents. */ -import {Disposable} from 'atom'; -import {Observable, Subject} from 'rxjs'; - -import { - observeActiveEditorsDebounced, - editorChangesDebounced, -} from './debounced'; - -import {observableFromSubscribeFunction} from '../commons-node/event'; -import {cacheWhileSubscribed} from '../commons-node/observable'; +const logger = (0, (_nuclideLogging || _load_nuclideLogging()).getLogger)(); -import {getLogger} from '../nuclide-logging'; -const logger = getLogger(); - -import ProviderRegistry from './ProviderRegistry'; - -export type Provider = { - priority: number, - grammarScopes: Array, - // This overrides the updateOnEdit setting in ActiveEditorRegistry's config. - updateOnEdit?: boolean, -}; - -export type Result = { - kind: 'not-text-editor', -} | { - kind: 'no-provider', - grammar: atom$Grammar, -} | { - kind: 'provider-error', - provider: T, -} | { - // Since providers can be slow, the pane-change and edit events are emitted immediately in case - // the UI needs to clear outdated results. - kind: 'pane-change', - editor: atom$TextEditor, -} | { - kind: 'edit', - editor: atom$TextEditor, -} | { - kind: 'save', - editor: atom$TextEditor, -} | { - kind: 'result', - result: V, - // The editor that the result was computed from - editor: atom$TextEditor, - // The provider that computed the result - // TODO Use a type paramater for this type - provider: T, -}; - -export type ResultFunction = (provider: T, editor: atom$TextEditor) => Promise; - -export type EventSources = { - activeEditors: Observable, - changesForEditor: (editor: atom$TextEditor) => Observable, - savesForEditor: (editor: atom$TextEditor) => Observable, -}; - -export type Config = { - /** - * If true, we will query providers for updates whenever the text in the editor is changed. - * Otherwise, we will query only when there is a save event. - */ - updateOnEdit?: boolean, -}; - -type ConcreteConfig = { - updateOnEdit: boolean, +const DEFAULT_CONFIG = { + updateOnEdit: true }; -const DEFAULT_CONFIG: ConcreteConfig = { - updateOnEdit: true, -}; - -function getConcreteConfig(config: Config): ConcreteConfig { - return { - ...DEFAULT_CONFIG, - ...config, - }; +function getConcreteConfig(config) { + return Object.assign({}, DEFAULT_CONFIG, config); } -export default class ActiveEditorRegistry { - _resultFunction: ResultFunction; - _providerRegistry: ProviderRegistry; - _newProviderEvents: Subject; - _resultsStream: Observable>; - _config: ConcreteConfig; - - constructor( - resultFunction: ResultFunction, - config: Config = {}, - eventSources: EventSources = getDefaultEventSources(), - ) { +class ActiveEditorRegistry { + + constructor(resultFunction, config = {}, eventSources = getDefaultEventSources()) { this._config = getConcreteConfig(config); this._resultFunction = resultFunction; - this._providerRegistry = new ProviderRegistry(); - this._newProviderEvents = new Subject(); + this._providerRegistry = new (_ProviderRegistry || _load_ProviderRegistry()).default(); + this._newProviderEvents = new _rxjsBundlesRxMinJs.Subject(); this._resultsStream = this._createResultsStream(eventSources); } - consumeProvider(provider: T): IDisposable { + consumeProvider(provider) { this._providerRegistry.addProvider(provider); this._newProviderEvents.next(); - return new Disposable(() => { + return new _atom.Disposable(() => { this._providerRegistry.removeProvider(provider); }); } - getResultsStream(): Observable> { + getResultsStream() { return this._resultsStream; } - _createResultsStream(eventSources: EventSources): Observable> { + _createResultsStream(eventSources) { const repeatedEditors = eventSources.activeEditors.switchMap(editor => { if (editor == null) { - return Observable.of(editor); + return _rxjsBundlesRxMinJs.Observable.of(editor); } - return Observable.concat( - Observable.of(editor), - this._newProviderEvents.mapTo(editor), - ); + return _rxjsBundlesRxMinJs.Observable.concat(_rxjsBundlesRxMinJs.Observable.of(editor), this._newProviderEvents.mapTo(editor)); }); const results = repeatedEditors.switchMap(editorArg => { // Necessary so the type refinement holds in the callback later const editor = editorArg; if (editor == null) { - return Observable.of({kind: 'not-text-editor'}); + return _rxjsBundlesRxMinJs.Observable.of({ kind: 'not-text-editor' }); } - return Observable.concat( - // Emit a pane change event first, so that clients can do something while waiting for a - // provider to give a result. - Observable.of({ - kind: 'pane-change', - editor, - }), - Observable.fromPromise(this._getResultForEditor( - this._getProviderForEditor(editor), - editor, - )), - this._resultsForEditor(editor, eventSources), - ); + return _rxjsBundlesRxMinJs.Observable.concat( + // Emit a pane change event first, so that clients can do something while waiting for a + // provider to give a result. + _rxjsBundlesRxMinJs.Observable.of({ + kind: 'pane-change', + editor + }), _rxjsBundlesRxMinJs.Observable.fromPromise(this._getResultForEditor(this._getProviderForEditor(editor), editor)), this._resultsForEditor(editor, eventSources)); }); - return cacheWhileSubscribed(results); + return (0, (_observable || _load_observable()).cacheWhileSubscribed)(results); } - _resultsForEditor(editor: atom$TextEditor, eventSources: EventSources): Observable> { + _resultsForEditor(editor, eventSources) { // It's possible that the active provider for an editor changes over time. // Thus, we have to subscribe to both edits and saves. - return Observable.merge( - eventSources.changesForEditor(editor) - .map(() => 'edit'), - eventSources.savesForEditor(editor) - .map(() => 'save'), - ).flatMap(event => { + return _rxjsBundlesRxMinJs.Observable.merge(eventSources.changesForEditor(editor).map(() => 'edit'), eventSources.savesForEditor(editor).map(() => 'save')).flatMap(event => { const provider = this._getProviderForEditor(editor); if (provider != null) { let updateOnEdit = provider.updateOnEdit; @@ -178,52 +126,55 @@ export default class ActiveEditorRegistry { updateOnEdit = this._config.updateOnEdit; } if (updateOnEdit !== (event === 'edit')) { - return Observable.empty(); + return _rxjsBundlesRxMinJs.Observable.empty(); } } - return Observable.concat( - // $FlowIssue: {kind: edit | save} <=> {kind: edit} | {kind: save} - Observable.of({kind: event, editor}), - Observable.fromPromise(this._getResultForEditor(provider, editor)), - ); + return _rxjsBundlesRxMinJs.Observable.concat( + // $FlowIssue: {kind: edit | save} <=> {kind: edit} | {kind: save} + _rxjsBundlesRxMinJs.Observable.of({ kind: event, editor }), _rxjsBundlesRxMinJs.Observable.fromPromise(this._getResultForEditor(provider, editor))); }); } - _getProviderForEditor(editor: atom$TextEditor): ?T { + _getProviderForEditor(editor) { return this._providerRegistry.getProviderForEditor(editor); } - async _getResultForEditor(provider: ?T, editor: atom$TextEditor): Promise> { - if (provider == null) { - return { - kind: 'no-provider', - grammar: editor.getGrammar(), - }; - } - try { - return { - kind: 'result', - result: await this._resultFunction(provider, editor), - provider, - editor, - }; - } catch (e) { - logger.error(`Error from provider for ${editor.getGrammar().scopeName}`, e); - return { - provider, - kind: 'provider-error', - }; - } + _getResultForEditor(provider, editor) { + var _this = this; + + return (0, _asyncToGenerator.default)(function* () { + if (provider == null) { + return { + kind: 'no-provider', + grammar: editor.getGrammar() + }; + } + try { + return { + kind: 'result', + result: yield _this._resultFunction(provider, editor), + provider, + editor + }; + } catch (e) { + logger.error(`Error from provider for ${editor.getGrammar().scopeName}`, e); + return { + provider, + kind: 'provider-error' + }; + } + })(); } } -function getDefaultEventSources(): EventSources { +exports.default = ActiveEditorRegistry; +function getDefaultEventSources() { return { - activeEditors: observeActiveEditorsDebounced(), - changesForEditor: editor => editorChangesDebounced(editor), + activeEditors: (0, (_debounced || _load_debounced()).observeActiveEditorsDebounced)(), + changesForEditor: editor => (0, (_debounced || _load_debounced()).editorChangesDebounced)(editor), savesForEditor: editor => { - return observableFromSubscribeFunction(callback => editor.onDidSave(callback)) - .mapTo(undefined); - }, + return (0, (_event || _load_event()).observableFromSubscribeFunction)(callback => editor.onDidSave(callback)).mapTo(undefined); + } }; } +module.exports = exports['default']; \ No newline at end of file diff --git a/pkg/commons-atom/AutocompleteCacher.js b/pkg/commons-atom/AutocompleteCacher.js index 3d2d231acc..538b94a9c4 100644 --- a/pkg/commons-atom/AutocompleteCacher.js +++ b/pkg/commons-atom/AutocompleteCacher.js @@ -1,3 +1,28 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _asyncToGenerator = _interopRequireDefault(require("async-to-generator")); + +let getNewFirstResult = (() => { + var _ref = (0, _asyncToGenerator.default)(function* (firstResultPromise, resultFromLanguageService) { + const firstResult = yield firstResultPromise; + if (firstResult != null) { + return firstResult; + } else { + return resultFromLanguageService; + } + }); + + return function getNewFirstResult(_x, _x2) { + return _ref.apply(this, arguments); + }; +})(); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,46 +30,20 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * */ -export type AutocompleteCacherConfig = {| - updateResults: ( - request: atom$AutocompleteRequest, - firstResult: T, - ) => T, - // If this is provided, we will ask it whether we can filter on the given request after first - // verifying that the cursor has only moved by one column since the last request. - shouldFilter?: ( - lastRequest: atom$AutocompleteRequest, - currentRequest: atom$AutocompleteRequest, - // TODO pass originalResult here if any client requires it - ) => boolean, -|}; - -type AutocompleteSession = { - firstResult: Promise, - lastRequest: atom$AutocompleteRequest, -}; - -export default class AutocompleteCacher { - _getSuggestions: (request: atom$AutocompleteRequest) => Promise; - _config: AutocompleteCacherConfig; - - _session: ?AutocompleteSession; +class AutocompleteCacher { constructor( - // If getSuggestions returns null or undefined, it means that we should not filter that result - // to serve later queries, even if shouldFilter returns true. If there are truly no results, it - // is recommended that getSuggestions return an empty Array. - getSuggestions: (request: atom$AutocompleteRequest) => Promise, - config: AutocompleteCacherConfig, - ) { + // If getSuggestions returns null or undefined, it means that we should not filter that result + // to serve later queries, even if shouldFilter returns true. If there are truly no results, it + getSuggestions, config) { this._getSuggestions = getSuggestions; this._config = config; } - getSuggestions(request: atom$AutocompleteRequest): Promise { + getSuggestions(request) { const session = this._session; if (session != null && this._canMaybeFilterResults(session, request)) { // We need to send this request speculatively because if firstResult resolves to `null`, we'll @@ -53,73 +52,50 @@ export default class AutocompleteCacher { // cases by checking if firstResult has already been resolved. If it has already resolved to a // non-null value, we can skip this request. const resultFromLanguageService = this._getSuggestions(request); - const result = this._filterSuggestionsIfPossible( - request, - session.firstResult, - resultFromLanguageService, - ); + const result = this._filterSuggestionsIfPossible(request, session.firstResult, resultFromLanguageService); this._session = { firstResult: getNewFirstResult(session.firstResult, resultFromLanguageService), - lastRequest: request, + lastRequest: request }; return result; } else { const result = this._getSuggestions(request); this._session = { firstResult: result, - lastRequest: request, + lastRequest: request }; return result; } } - async _filterSuggestionsIfPossible( - request: atom$AutocompleteRequest, - firstResultPromise: Promise, - resultFromLanguageService: Promise, - ): Promise { - const firstResult = await firstResultPromise; - if (firstResult != null) { - return this._config.updateResults(request, firstResult); - } else { - return resultFromLanguageService; - } + _filterSuggestionsIfPossible(request, firstResultPromise, resultFromLanguageService) { + var _this = this; + + return (0, _asyncToGenerator.default)(function* () { + const firstResult = yield firstResultPromise; + if (firstResult != null) { + return _this._config.updateResults(request, firstResult); + } else { + return resultFromLanguageService; + } + })(); } // This doesn't guarantee we can filter results -- if the previous result turns out to be null, we // may still have to use the results from the language service. - _canMaybeFilterResults( - session: AutocompleteSession, - currentRequest: atom$AutocompleteRequest, - ): boolean { - const {lastRequest} = session; - const shouldFilter = this._config.shouldFilter != null ? - this._config.shouldFilter : - defaultShouldFilter; - return lastRequest.bufferPosition.row === currentRequest.bufferPosition.row && - lastRequest.bufferPosition.column + 1 === currentRequest.bufferPosition.column && - shouldFilter(lastRequest, currentRequest); + _canMaybeFilterResults(session, currentRequest) { + const { lastRequest } = session; + const shouldFilter = this._config.shouldFilter != null ? this._config.shouldFilter : defaultShouldFilter; + return lastRequest.bufferPosition.row === currentRequest.bufferPosition.row && lastRequest.bufferPosition.column + 1 === currentRequest.bufferPosition.column && shouldFilter(lastRequest, currentRequest); } } -async function getNewFirstResult( - firstResultPromise: Promise, - resultFromLanguageService: Promise, -): Promise { - const firstResult = await firstResultPromise; - if (firstResult != null) { - return firstResult; - } else { - return resultFromLanguageService; - } -} +exports.default = AutocompleteCacher; + const IDENTIFIER_CHAR_REGEX = /[a-zA-Z_]/; -function defaultShouldFilter( - lastRequest: atom$AutocompleteRequest, - currentRequest: atom$AutocompleteRequest, -) { - return currentRequest.prefix.startsWith(lastRequest.prefix) && - IDENTIFIER_CHAR_REGEX.test(currentRequest.prefix.charAt(currentRequest.prefix.length - 1)); +function defaultShouldFilter(lastRequest, currentRequest) { + return currentRequest.prefix.startsWith(lastRequest.prefix) && IDENTIFIER_CHAR_REGEX.test(currentRequest.prefix.charAt(currentRequest.prefix.length - 1)); } +module.exports = exports["default"]; \ No newline at end of file diff --git a/pkg/commons-atom/ContextMenu.js b/pkg/commons-atom/ContextMenu.js index 419f9bb6d2..7a12990566 100644 --- a/pkg/commons-atom/ContextMenu.js +++ b/pkg/commons-atom/ContextMenu.js @@ -1,43 +1,10 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the license found in the LICENSE file in - * the root directory of this source tree. - * - * @flow - */ - -import {Disposable} from 'atom'; -import invariant from 'assert'; - -type Item = { - type: 'item', - item: atom$ContextMenuItem, - priority: number, -}; - -type Menu = { - type: 'menu', - menu: ContextMenu, - priority: number, -}; +'use strict'; -type InternalItem = Item | Menu; +Object.defineProperty(exports, "__esModule", { + value: true +}); -type RootMenuOptions = { - type: 'root', - cssSelector: string, -}; - -type SubmenuOptions = { - type: 'submenu', - label: string, - parent: ContextMenu, - shouldDisplay?: (e: MouseEvent) => boolean, -}; - -type MenuOptions = RootMenuOptions | SubmenuOptions; +var _atom = require('atom'); /** * This class represents a collection of context menu items that have been registered with Atom's @@ -54,28 +21,14 @@ type MenuOptions = RootMenuOptions | SubmenuOptions; * Note that this class also provides support for submenu items. This requires Atom 1.6 or later * because it relies on this fix: https://github.com/atom/atom/pull/10486. */ -export default class ContextMenu { - _menuOptions: MenuOptions; +class ContextMenu { /** * List of items that have been added to this context menu in the order they were added. * Note that this list does not get sorted: only a filtered version of it does. * Further, this list is mutated heavily, but it is never reassigned. */ - _items: Array; - - _needsSort: boolean; - _sort: Function; - - /** - * This is the Disposable that represents adding all of this object's menu items to Atom's own - * ContextMenuManager. When a new item is added to this object, we must remove all of the items - * that we previously added to the ContextMenuManager and then re-add them based on the new - * ordering of priorities that results from the new item. - */ - _disposable: ?IDisposable; - - constructor(menuOptions: MenuOptions) { + constructor(menuOptions) { this._menuOptions = menuOptions; this._items = []; this._needsSort = false; @@ -87,7 +40,15 @@ export default class ContextMenu { * @return true if this menu does not contain any items; otherwise, returns false. Note this will * return true if it contains only empty submenu items. */ - isEmpty(): boolean { + + + /** + * This is the Disposable that represents adding all of this object's menu items to Atom's own + * ContextMenuManager. When a new item is added to this object, we must remove all of the items + * that we previously added to the ContextMenuManager and then re-add them based on the new + * ordering of priorities that results from the new item. + */ + isEmpty() { return this._items.length === 0; } @@ -99,8 +60,8 @@ export default class ContextMenu { * * @return object whose dispose() method can be used to remove the menu item from this object. */ - addItem(item: atom$ContextMenuItem, priority: number): IDisposable { - const value = {type: 'item', item, priority}; + addItem(item, priority) { + const value = { type: 'item', item, priority }; return this._addItemToList(value); } @@ -112,19 +73,19 @@ export default class ContextMenu { * * @return object whose dispose() method can be used to remove the submenu from this object. */ - addSubmenu(contextMenu: ContextMenu, priority: number): IDisposable { - const value = {type: 'menu', menu: contextMenu, priority}; + addSubmenu(contextMenu, priority) { + const value = { type: 'menu', menu: contextMenu, priority }; return this._addItemToList(value); } - _addItemToList(value: InternalItem): IDisposable { + _addItemToList(value) { this._items.push(value); this._needsSort = true; process.nextTick(this._sort); // TODO(mbolin): Ideally, this Disposable should be garbage-collected if this ContextMenu is // disposed. - return new Disposable(() => { + return new _atom.Disposable(() => { const index = this._items.indexOf(value); this._items.splice(index, 1); @@ -139,7 +100,7 @@ export default class ContextMenu { * all items that this object previously registered with Atom's ContextMenuManager. Then it will * re-register everything in this._items once it has been sorted. */ - _sort(): void { + _sort() { if (!this._needsSort) { return; } @@ -154,7 +115,7 @@ export default class ContextMenu { if (menuOptions.type === 'root') { const items = this._sortAndFilterItems(); this._disposable = atom.contextMenu.add({ - [menuOptions.cssSelector]: items.map(this._contextMenuItemForInternalItem, this), + [menuOptions.cssSelector]: items.map(this._contextMenuItemForInternalItem, this) }); } else if (menuOptions.type === 'submenu') { // Tell the parent menu to sort itself. @@ -164,27 +125,33 @@ export default class ContextMenu { } /** Translates this object's internal representation of a menu item to Atom's representation. */ - _contextMenuItemForInternalItem(internalItem: InternalItem): atom$ContextMenuItem { + _contextMenuItemForInternalItem(internalItem) { if (internalItem.type === 'item') { return internalItem.item; } else if (internalItem.type === 'menu') { // Note that due to our own strict renaming rules, this must be a private method instead of a // static function becuase of the access to _menuOptions and _items. const menuOptions = internalItem.menu._menuOptions; - invariant(menuOptions.type === 'submenu'); + + if (!(menuOptions.type === 'submenu')) { + throw new Error('Invariant violation: "menuOptions.type === \'submenu\'"'); + } + const items = internalItem.menu._sortAndFilterItems(); return { label: menuOptions.label, submenu: items.map(this._contextMenuItemForInternalItem, this), - shouldDisplay: menuOptions.shouldDisplay, + shouldDisplay: menuOptions.shouldDisplay }; } else { - invariant(false); + if (!false) { + throw new Error('Invariant violation: "false"'); + } } } - _sortAndFilterItems(): Array { - const items = this._items.filter((item: InternalItem) => { + _sortAndFilterItems() { + const items = this._items.filter(item => { if (item.type === 'item') { return true; } else if (item.type === 'menu') { @@ -206,7 +173,18 @@ export default class ContextMenu { } } -/** Comparator used to sort menu items by priority: lower priorities appear earlier. */ -function compareInternalItems(a: InternalItem, b: InternalItem): number { +exports.default = ContextMenu; /** Comparator used to sort menu items by priority: lower priorities appear earlier. */ +/** + * Copyright (c) 2015-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the license found in the LICENSE file in + * the root directory of this source tree. + * + * + */ + +function compareInternalItems(a, b) { return a.priority - b.priority; } +module.exports = exports['default']; \ No newline at end of file diff --git a/pkg/commons-atom/LocalStorageJsonTable.js b/pkg/commons-atom/LocalStorageJsonTable.js index 23718bd410..201fc23ec7 100644 --- a/pkg/commons-atom/LocalStorageJsonTable.js +++ b/pkg/commons-atom/LocalStorageJsonTable.js @@ -1,45 +1,37 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the license found in the LICENSE file in - * the root directory of this source tree. - * - * @flow - */ +'use strict'; -/* global localStorage */ +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.LocalStorageJsonTable = undefined; -import {nextAnimationFrame} from '../commons-node/observable'; +var _observable; -type Entry = {key: string, value: T}; +function _load_observable() { + return _observable = require('../commons-node/observable'); +} -export class LocalStorageJsonTable { - _localStorageKey: string; - _db: ?Array>; - _clearCacheSubscription: ?rxjs$Subscription; - _cacheSize: number; +class LocalStorageJsonTable { - constructor(localStorageKey: string, cacheSize: number = 100) { + constructor(localStorageKey, cacheSize = 100) { this._localStorageKey = localStorageKey; this._cacheSize = cacheSize; } - _open(): Array> { + _open() { if (this._db == null) { const json = localStorage.getItem(this._localStorageKey); let db; if (json != null && json !== '') { try { db = JSON.parse(json); - } catch (err) { - } + } catch (err) {} } this._db = Array.isArray(db) ? db : []; // Clear the cache after this frame. We have to do this because other windows might be // interacting with the database too. if (this._clearCacheSubscription == null) { - this._clearCacheSubscription = nextAnimationFrame.subscribe(() => { + this._clearCacheSubscription = (_observable || _load_observable()).nextAnimationFrame.subscribe(() => { this._db = null; this._clearCacheSubscription = null; }); @@ -48,15 +40,15 @@ export class LocalStorageJsonTable { return this._db; } - dispose(): void { + dispose() { if (this._clearCacheSubscription != null) { this._clearCacheSubscription.unsubscribe(); } } - setItem(key: string, value: T): void { + setItem(key, value) { let db = this._open(); - const matchIndex = db.findIndex(({key: k}) => k === key); + const matchIndex = db.findIndex(({ key: k }) => k === key); if (matchIndex !== -1) { const previousValue = db[matchIndex].value; // No reason to drop and re-push the most recent value @@ -65,18 +57,29 @@ export class LocalStorageJsonTable { } db.splice(matchIndex, 1); } - db.push({key, value}); + db.push({ key, value }); db = db.slice(-this._cacheSize); localStorage.setItem(this._localStorageKey, JSON.stringify(db)); } - getItem(key: string): ?T { + getItem(key) { const db = this._open(); - const entry = db.find(({key: k}) => key === k); + const entry = db.find(({ key: k }) => key === k); return entry == null ? null : entry.value; } - getEntries(): Array> { + getEntries() { return this._open().slice(); } } +exports.LocalStorageJsonTable = LocalStorageJsonTable; /** + * Copyright (c) 2015-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the license found in the LICENSE file in + * the root directory of this source tree. + * + * + */ + +/* global localStorage */ \ No newline at end of file diff --git a/pkg/commons-atom/PanelRenderer.js b/pkg/commons-atom/PanelRenderer.js index c2888025e3..07478e045a 100644 --- a/pkg/commons-atom/PanelRenderer.js +++ b/pkg/commons-atom/PanelRenderer.js @@ -1,3 +1,13 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + + +/** + * A class that gives us an idempotent API for rendering panels, creating them lazily. + */ /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,41 +15,24 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * */ -type PanelLocation = 'top' | 'right' | 'bottom' | 'left'; -type Options = { - location: PanelLocation, - createItem: () => Object, - priority?: number, -}; - -/** - * A class that gives us an idempotent API for rendering panels, creating them lazily. - */ -export default class PanelRenderer { - _createItem: () => Object; - _item: ?Object; - _location: PanelLocation; - _panel: ?atom$Panel; - _priority: ?number; +class PanelRenderer { - constructor(options: Options) { + constructor(options) { this._createItem = options.createItem; this._location = options.location; this._priority = options.priority; } - render(props: {visible: boolean}): void { + render(props) { if (props.visible) { if (this._panel == null) { - const item = this._item == null - ? this._item = this._createItem() - : this._item; + const item = this._item == null ? this._item = this._createItem() : this._item; this._panel = addPanel(this._location, { item, - priority: this._priority == null ? undefined : this._priority, + priority: this._priority == null ? undefined : this._priority }); } else { this._panel.show(); @@ -49,7 +42,7 @@ export default class PanelRenderer { } } - dispose(): void { + dispose() { if (this._item != null && typeof this._item.destroy === 'function') { this._item.destroy(); } @@ -59,7 +52,8 @@ export default class PanelRenderer { } } -function addPanel(location: PanelLocation, options: atom$WorkspaceAddPanelOptions): atom$Panel { +exports.default = PanelRenderer; +function addPanel(location, options) { switch (location) { case 'top': return atom.workspace.addTopPanel(options); @@ -73,3 +67,4 @@ function addPanel(location: PanelLocation, options: atom$WorkspaceAddPanelOption throw new Error(`Invalid location: ${location}`); } } +module.exports = exports['default']; \ No newline at end of file diff --git a/pkg/commons-atom/ProviderRegistry.js b/pkg/commons-atom/ProviderRegistry.js index 00f9ac8bfc..66f92198fb 100644 --- a/pkg/commons-atom/ProviderRegistry.js +++ b/pkg/commons-atom/ProviderRegistry.js @@ -1,39 +1,28 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the license found in the LICENSE file in - * the root directory of this source tree. - * - * @flow - */ +"use strict"; -export type Provider = { - priority: number, - grammarScopes: Array, -}; - -export default class ProviderRegistry { - _providers: Set; +Object.defineProperty(exports, "__esModule", { + value: true +}); +class ProviderRegistry { constructor() { this._providers = new Set(); } - addProvider(provider: T): void { + addProvider(provider) { this._providers.add(provider); } - removeProvider(provider: T): void { + removeProvider(provider) { this._providers.delete(provider); } - getProviderForEditor(editor: atom$TextEditor): ?T { + getProviderForEditor(editor) { const grammar = editor.getGrammar().scopeName; return this.findProvider(grammar); } - findProvider(grammar: string): ?T { + findProvider(grammar) { let bestProvider = null; let bestPriority = Number.NEGATIVE_INFINITY; for (const provider of this._providers) { @@ -47,3 +36,14 @@ export default class ProviderRegistry { return bestProvider; } } +exports.default = ProviderRegistry; /** + * Copyright (c) 2015-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the license found in the LICENSE file in + * the root directory of this source tree. + * + * + */ + +module.exports = exports["default"]; \ No newline at end of file diff --git a/pkg/commons-atom/arcanist.js b/pkg/commons-atom/arcanist.js index c1a042b922..20131297d9 100644 --- a/pkg/commons-atom/arcanist.js +++ b/pkg/commons-atom/arcanist.js @@ -1,3 +1,26 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.findArcProjectIdAndDirectory = findArcProjectIdAndDirectory; +exports.getCachedArcProjectIdAndDirectory = getCachedArcProjectIdAndDirectory; +exports.getLastProjectPath = getLastProjectPath; + +var _lruCache; + +function _load_lruCache() { + return _lruCache = _interopRequireDefault(require('lru-cache')); +} + +var _nuclideRemoteConnection; + +function _load_nuclideRemoteConnection() { + return _nuclideRemoteConnection = require('../nuclide-remote-connection'); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,21 +28,13 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * */ /* global localStorage */ -import LRUCache from 'lru-cache'; -import {getArcanistServiceByNuclideUri} from '../nuclide-remote-connection'; - -export type ArcProjectInfo = { - projectId: string, - directory: string, -}; - -const arcInfoCache: LRUCache> = new LRUCache({max: 200}); -const arcInfoResultCache: LRUCache = new LRUCache({max: 200}); +const arcInfoCache = new (_lruCache || _load_lruCache()).default({ max: 200 }); +const arcInfoResultCache = new (_lruCache || _load_lruCache()).default({ max: 200 }); const STORAGE_KEY = 'nuclide.last-arc-project-path'; /** @@ -27,27 +42,22 @@ const STORAGE_KEY = 'nuclide.last-arc-project-path'; * The service also caches this, but since this is called so frequently we should * try to avoid going over the RPC layer as well. */ -export function findArcProjectIdAndDirectory(src: string): Promise { +function findArcProjectIdAndDirectory(src) { let cached = arcInfoCache.get(src); if (cached == null) { - const arcService = getArcanistServiceByNuclideUri(src); - cached = arcService.findArcProjectIdAndDirectory(src) - .then(result => { - // Store the path in local storage for `getLastProjectPath`. - if (result != null) { - localStorage.setItem( - `${STORAGE_KEY}.${result.projectId}`, - result.directory, - ); - } - arcInfoResultCache.set(src, result); - return result; - }) - .catch(err => { - // Clear the cache if there's an error to enable retries. - arcInfoCache.del(src); - return Promise.reject(err); - }); + const arcService = (0, (_nuclideRemoteConnection || _load_nuclideRemoteConnection()).getArcanistServiceByNuclideUri)(src); + cached = arcService.findArcProjectIdAndDirectory(src).then(result => { + // Store the path in local storage for `getLastProjectPath`. + if (result != null) { + localStorage.setItem(`${STORAGE_KEY}.${result.projectId}`, result.directory); + } + arcInfoResultCache.set(src, result); + return result; + }).catch(err => { + // Clear the cache if there's an error to enable retries. + arcInfoCache.del(src); + return Promise.reject(err); + }); arcInfoCache.set(src, cached); } return cached; @@ -58,10 +68,10 @@ export function findArcProjectIdAndDirectory(src: string): Promise, - customProps: Object, -}; +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.syncBlockDecorations = syncBlockDecorations; +var _reactForAtom = require('react-for-atom'); /** * Instead of destroying all the decorations and re-rendering them on each edit, @@ -29,18 +20,11 @@ type BlockElementWithProps = { * * @return an array of markers to be destroyed when the decorations are no longer needed. */ -export function syncBlockDecorations( - editorElement: atom$TextEditorElement, - diffBlockType: string, - source: Map, - shouldUpdate: (value: Value, properties: Object) => boolean, - getElementWithProps: (value: Value) => BlockElementWithProps, - syncWidth?: boolean = false, -): Array { +function syncBlockDecorations(editorElement, diffBlockType, source, shouldUpdate, getElementWithProps, syncWidth = false) { const editor = editorElement.getModel(); - const decorations = editor.getDecorations({diffBlockType}); + const decorations = editor.getDecorations({ diffBlockType }); const renderedLineNumbers = new Set(); - const {component} = editorElement; + const { component } = editorElement; const markers = []; @@ -49,7 +33,7 @@ export function syncBlockDecorations( const lineNumber = marker.getBufferRange().start.row; const value = source.get(lineNumber); const properties = decoration.getProperties(); - const item: HTMLElement = properties.item; + const item = properties.item; // If the decoration should no longer exist or it has already been rendered, // it needs to be destroyed. @@ -59,8 +43,8 @@ export function syncBlockDecorations( } if (shouldUpdate(value, properties)) { - const {element, customProps} = getElementWithProps(value); - ReactDOM.render(element, item); + const { element, customProps } = getElementWithProps(value); + _reactForAtom.ReactDOM.render(element, item); Object.assign(properties, customProps); @@ -80,25 +64,32 @@ export function syncBlockDecorations( continue; } - const {element, customProps} = getElementWithProps(value); - const marker = editor.markBufferPosition([lineNumber, 0], {invalidate: 'never'}); + const { element, customProps } = getElementWithProps(value); + const marker = editor.markBufferPosition([lineNumber, 0], { invalidate: 'never' }); // The position should be `after` if the element is at the end of the file. const position = lineNumber >= editor.getLineCount() - 1 ? 'after' : 'before'; const item = document.createElement('div'); - ReactDOM.render(element, item); + _reactForAtom.ReactDOM.render(element, item); marker.onDidDestroy(() => { - ReactDOM.unmountComponentAtNode(item); + _reactForAtom.ReactDOM.unmountComponentAtNode(item); }); - editor.decorateMarker(marker, { - ...customProps, + editor.decorateMarker(marker, Object.assign({}, customProps, { type: 'block', item, - position, - }); + position + })); markers.push(marker); } return markers; -} +} /** + * Copyright (c) 2015-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the license found in the LICENSE file in + * the root directory of this source tree. + * + * + */ \ No newline at end of file diff --git a/pkg/commons-atom/browser-cookies.js b/pkg/commons-atom/browser-cookies.js index 03fd51fb86..532d12648c 100644 --- a/pkg/commons-atom/browser-cookies.js +++ b/pkg/commons-atom/browser-cookies.js @@ -1,3 +1,13 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _electron = _interopRequireDefault(require('electron')); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,21 +15,21 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * */ -import invariant from 'assert'; -import electron from 'electron'; +const { remote } = _electron.default; -const {remote} = electron; -invariant(remote != null); +if (!(remote != null)) { + throw new Error('Invariant violation: "remote != null"'); +} -export default { - getCookies(domain: string): Promise<{[key: string]: string}> { +exports.default = { + getCookies(domain) { return new Promise((resolve, reject) => { // $FlowFixMe: Add types for electron$WebContents remote.getCurrentWindow().webContents.session.cookies.get({ - domain, + domain }, (error, cookies) => { if (error) { reject(error); @@ -34,14 +44,14 @@ export default { }); }, - setCookie(url: string, domain: string, name: string, value: string): Promise { + setCookie(url, domain, name, value) { return new Promise((resolve, reject) => { // $FlowFixMe: Add types for electron$WebContents remote.getCurrentWindow().webContents.session.cookies.set({ url, domain, name, - value, + value }, error => { if (error) { reject(error); @@ -50,5 +60,6 @@ export default { } }); }); - }, + } }; +module.exports = exports['default']; \ No newline at end of file diff --git a/pkg/commons-atom/consumeFirstProvider.js b/pkg/commons-atom/consumeFirstProvider.js index f0d043992f..7fd8c702e9 100644 --- a/pkg/commons-atom/consumeFirstProvider.js +++ b/pkg/commons-atom/consumeFirstProvider.js @@ -1,3 +1,9 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = consumeFirstProvider; /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,7 +11,7 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * */ /** @@ -13,17 +19,14 @@ * https://github.com/atom/service-hub/issues/6 */ -export default function consumeFirstProvider( - keyPath: string, - version: string = '0.0.0', -): Promise { +function consumeFirstProvider(keyPath, version = '0.0.0') { return new Promise((resolve, reject) => { - const subscription = - atom.packages.serviceHub.consume(keyPath, version, provider => { - process.nextTick(() => { - resolve(provider); - subscription.dispose(); - }); + const subscription = atom.packages.serviceHub.consume(keyPath, version, provider => { + process.nextTick(() => { + resolve(provider); + subscription.dispose(); }); + }); }); } +module.exports = exports['default']; \ No newline at end of file diff --git a/pkg/commons-atom/create-pane-container.js b/pkg/commons-atom/create-pane-container.js index f6213f060f..6dc173bbb3 100644 --- a/pkg/commons-atom/create-pane-container.js +++ b/pkg/commons-atom/create-pane-container.js @@ -1,3 +1,9 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = createPaneContainer; /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,15 +11,16 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * */ -export default function createPaneContainer(): Object { +function createPaneContainer() { const PaneContainer = atom.workspace.paneContainer.constructor; return new PaneContainer({ config: atom.config, applicationDelegate: atom.applicationDelegate, notificationManager: atom.notifications, - deserializerManager: atom.deserializers, + deserializerManager: atom.deserializers }); } +module.exports = exports["default"]; \ No newline at end of file diff --git a/pkg/commons-atom/createPackage.js b/pkg/commons-atom/createPackage.js index 360c8b9a8f..4ed49d4583 100644 --- a/pkg/commons-atom/createPackage.js +++ b/pkg/commons-atom/createPackage.js @@ -1,14 +1,10 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the license found in the LICENSE file in - * the root directory of this source tree. - * - * @flow - */ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = createPackage; -import invariant from 'assert'; /** * Create an Atom package from an Activation constructor. @@ -19,7 +15,7 @@ import invariant from 'assert'; * sense to build packages as instances, constructed when a package is activated and destroyed when * the package is deactivated. */ -export default function createPackage(Activation: Class): Object { +function createPackage(Activation) { let activation = null; const pkg = {}; @@ -32,48 +28,59 @@ export default function createPackage(Activation: Class): Object { continue; } if (property === 'activate') { - throw new Error( - 'Your activation class contains an "activate" method, but that work should be done in the' - + ' constructor.', - ); + throw new Error('Your activation class contains an "activate" method, but that work should be done in the' + ' constructor.'); } if (property === 'deactivate') { - throw new Error( - 'Your activation class contains an "deactivate" method. Please use "dispose" instead.', - ); + throw new Error('Your activation class contains an "deactivate" method. Please use "dispose" instead.'); } - pkg[property] = function(...args) { - invariant(activation != null, 'Package not activated'); + pkg[property] = function (...args) { + if (!(activation != null)) { + throw new Error('Package not activated'); + } + return activation[property](...args); }; } - return { - ...pkg, + return Object.assign({}, pkg, { /** * Calling `activate()` creates a new instance. */ - activate(initialState: ?Object): void { - invariant(activation == null, 'Package already activated'); + activate(initialState) { + if (!(activation == null)) { + throw new Error('Package already activated'); + } + activation = new Activation(initialState); }, /** * The `deactivate()` method is special-cased to null our activation instance reference. */ - deactivate(): void { - invariant(activation != null, 'Package not activated'); + deactivate() { + if (!(activation != null)) { + throw new Error('Package not activated'); + } + if (typeof activation.dispose === 'function') { activation.dispose(); } activation = null; - }, - }; -} + } + }); +} /** + * Copyright (c) 2015-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the license found in the LICENSE file in + * the root directory of this source tree. + * + * + */ -function getPrototypeChain(prototype: Class): Array> { +function getPrototypeChain(prototype) { let currentPrototype = prototype; const prototypes = []; while (currentPrototype != null) { @@ -87,10 +94,10 @@ function getPrototypeChain(prototype: Class): Array> { * List the properties (including inherited ones) of the provided prototype, excluding the ones * inherited from `Object`. */ -function getPropertyList(prototype: Class): Array { +function getPropertyList(prototype) { const properties = []; for (const proto of getPrototypeChain(prototype)) { - if (proto === (Object: any).prototype) { + if (proto === Object.prototype) { break; } for (const property of Object.getOwnPropertyNames(proto)) { @@ -99,3 +106,4 @@ function getPropertyList(prototype: Class): Array { } return properties; } +module.exports = exports['default']; \ No newline at end of file diff --git a/pkg/commons-atom/debounced.js b/pkg/commons-atom/debounced.js index 0b06808615..4a5e4223a7 100644 --- a/pkg/commons-atom/debounced.js +++ b/pkg/commons-atom/debounced.js @@ -1,12 +1,37 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the license found in the LICENSE file in - * the root directory of this source tree. - * - * @flow - */ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.observeActivePaneItemDebounced = observeActivePaneItemDebounced; +exports.observeActiveEditorsDebounced = observeActiveEditorsDebounced; +exports.editorChangesDebounced = editorChangesDebounced; +exports.editorScrollTopDebounced = editorScrollTopDebounced; +exports.observeTextEditorsPositions = observeTextEditorsPositions; + +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js'); + +var _event; + +function _load_event() { + return _event = require('../commons-node/event'); +} + +var _textEditor; + +function _load_textEditor() { + return _textEditor = require('./text-editor'); +} + +const DEFAULT_PANE_DEBOUNCE_INTERVAL_MS = 100; /** + * Copyright (c) 2015-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the license found in the LICENSE file in + * the root directory of this source tree. + * + * + */ /** * Often, we may want to respond to Atom events, but only after a buffer period @@ -17,78 +42,47 @@ * This file provides methods to do this. */ -import {Observable} from 'rxjs'; - -import {observableFromSubscribeFunction} from '../commons-node/event'; -import {getCursorPositions, isValidTextEditor} from './text-editor'; -import invariant from 'assert'; - -const DEFAULT_PANE_DEBOUNCE_INTERVAL_MS = 100; const DEFAULT_EDITOR_DEBOUNCE_INTERVAL_MS = 300; const DEFAULT_POSITION_DEBOUNCE_INTERVAL_MS = 300; -export function observeActivePaneItemDebounced( - debounceInterval: number = DEFAULT_PANE_DEBOUNCE_INTERVAL_MS, -): Observable { - return observableFromSubscribeFunction(callback => { +function observeActivePaneItemDebounced(debounceInterval = DEFAULT_PANE_DEBOUNCE_INTERVAL_MS) { + return (0, (_event || _load_event()).observableFromSubscribeFunction)(callback => { return atom.workspace.observeActivePaneItem(callback); - }) - .debounceTime(debounceInterval); + }).debounceTime(debounceInterval); } -export function observeActiveEditorsDebounced( - debounceInterval: number = DEFAULT_PANE_DEBOUNCE_INTERVAL_MS, -): Observable { - return observeActivePaneItemDebounced(debounceInterval) - .map(paneItem => { - if (isValidTextEditor(paneItem)) { - // Flow cannot understand the type refinement provided by the isValidTextEditor function, - // so we have to cast. - return ((paneItem: any): atom$TextEditor); - } - return null; - }); +function observeActiveEditorsDebounced(debounceInterval = DEFAULT_PANE_DEBOUNCE_INTERVAL_MS) { + return observeActivePaneItemDebounced(debounceInterval).map(paneItem => { + if ((0, (_textEditor || _load_textEditor()).isValidTextEditor)(paneItem)) { + // Flow cannot understand the type refinement provided by the isValidTextEditor function, + // so we have to cast. + return paneItem; + } + return null; + }); } -export function editorChangesDebounced( - editor: atom$TextEditor, - debounceInterval: number = DEFAULT_EDITOR_DEBOUNCE_INTERVAL_MS, -): Observable { - return observableFromSubscribeFunction(callback => editor.onDidChange(callback)) - // Debounce manually rather than using editor.onDidStopChanging so that the debounce time is - // configurable. - .debounceTime(debounceInterval); +function editorChangesDebounced(editor, debounceInterval = DEFAULT_EDITOR_DEBOUNCE_INTERVAL_MS) { + return (0, (_event || _load_event()).observableFromSubscribeFunction)(callback => editor.onDidChange(callback)) + // Debounce manually rather than using editor.onDidStopChanging so that the debounce time is + // configurable. + .debounceTime(debounceInterval); } -export function editorScrollTopDebounced( - editor: atom$TextEditor, - debounceInterval: number = DEFAULT_EDITOR_DEBOUNCE_INTERVAL_MS, -): Observable { - return observableFromSubscribeFunction( - callback => atom.views.getView(editor).onDidChangeScrollTop(callback), - ).debounceTime(debounceInterval); +function editorScrollTopDebounced(editor, debounceInterval = DEFAULT_EDITOR_DEBOUNCE_INTERVAL_MS) { + return (0, (_event || _load_event()).observableFromSubscribeFunction)(callback => atom.views.getView(editor).onDidChangeScrollTop(callback)).debounceTime(debounceInterval); } -export type EditorPosition = { - editor: atom$TextEditor, - position: atom$Point, -}; - // Yields null when the current pane is not an editor, // otherwise yields events on each move of the primary cursor within any Editor. -export function observeTextEditorsPositions( - editorDebounceInterval: number = DEFAULT_EDITOR_DEBOUNCE_INTERVAL_MS, - positionDebounceInterval: number = DEFAULT_POSITION_DEBOUNCE_INTERVAL_MS, -): Observable { - return observeActiveEditorsDebounced(editorDebounceInterval).switchMap( - editor => { - return editor == null - ? Observable.of(null) - : getCursorPositions(editor) - .debounceTime(positionDebounceInterval) - .map(position => { - invariant(editor != null); - return {editor, position}; - }); +function observeTextEditorsPositions(editorDebounceInterval = DEFAULT_EDITOR_DEBOUNCE_INTERVAL_MS, positionDebounceInterval = DEFAULT_POSITION_DEBOUNCE_INTERVAL_MS) { + return observeActiveEditorsDebounced(editorDebounceInterval).switchMap(editor => { + return editor == null ? _rxjsBundlesRxMinJs.Observable.of(null) : (0, (_textEditor || _load_textEditor()).getCursorPositions)(editor).debounceTime(positionDebounceInterval).map(position => { + if (!(editor != null)) { + throw new Error('Invariant violation: "editor != null"'); + } + + return { editor, position }; }); -} + }); +} \ No newline at end of file diff --git a/pkg/commons-atom/destroy-pane-item.js b/pkg/commons-atom/destroy-pane-item.js index 7e21b2f55a..4aa0f2fba3 100644 --- a/pkg/commons-atom/destroy-pane-item.js +++ b/pkg/commons-atom/destroy-pane-item.js @@ -1,3 +1,9 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = destroyPaneItemWithTitle; /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,10 +11,10 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * */ -export default function destroyPaneItemWithTitle(title: string) { +function destroyPaneItemWithTitle(title) { for (const item of atom.workspace.getPaneItems()) { if (item.getTitle() === title) { const pane = atom.workspace.paneForItem(item); @@ -19,3 +25,4 @@ export default function destroyPaneItemWithTitle(title: string) { } } } +module.exports = exports["default"]; \ No newline at end of file diff --git a/pkg/commons-atom/featureConfig.js b/pkg/commons-atom/featureConfig.js index f8c7d70bae..ee0ddd148d 100644 --- a/pkg/commons-atom/featureConfig.js +++ b/pkg/commons-atom/featureConfig.js @@ -1,18 +1,22 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the license found in the LICENSE file in - * the root directory of this source tree. - * - * @flow - */ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); -import {Observable} from 'rxjs'; +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js'); -const NUCLIDE_CONFIG_SCOPE = 'nuclide.'; +const NUCLIDE_CONFIG_SCOPE = 'nuclide.'; /** + * Copyright (c) 2015-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the license found in the LICENSE file in + * the root directory of this source tree. + * + * + */ -function formatKeyPath(keyPath: string): string { +function formatKeyPath(keyPath) { return `${NUCLIDE_CONFIG_SCOPE}${keyPath}`; } @@ -28,29 +32,14 @@ function formatKeyPath(keyPath: string): string { * Example: * const config: MyConfigType = (featureConfig.get('config-name'): any); */ -function get( - keyPath: string, - options?: { - excludeSources?: Array, - sources?: Array, - scope?: Object, - }, -): mixed { +function get(keyPath, options) { // atom.config.get will crash if the second arg is present and undefined. // It does not crash if the second arg is missing. return atom.config.get(formatKeyPath(keyPath), ...(options == null ? [] : [options])); } -function getWithDefaults( - keyPath: string, - defaults: T, - options?: { - excludeSources?: Array, - sources?: Array, - scope?: Object, - }, -): T { - const current: any = get(keyPath, options); +function getWithDefaults(keyPath, defaults, options) { + const current = get(keyPath, options); return current == null ? defaults : current; } @@ -58,9 +47,7 @@ function getWithDefaults( * Gets the schema of a setting for a Nuclide feature key. Takes and returns the same types as * `atom.config.getSchema`. */ -function getSchema( - keyPath: string, -): atom$ConfigSchema { +function getSchema(keyPath) { return atom.config.getSchema(formatKeyPath(keyPath)); } @@ -69,10 +56,7 @@ function getSchema( * * To observe changes on the entire config, use `atom.config.observe`. */ -function observe( - keyPath: string, - callback: (value: mixed) => mixed, -): IDisposable { +function observe(keyPath, callback) { return atom.config.observe(formatKeyPath(keyPath), callback); } @@ -80,8 +64,8 @@ function observe( * Behaves similarly to the `observe` function, but returns a stream of values, rather * then receiving a callback. */ -function observeAsStream(keyPath: string): Observable { - return Observable.create(observer => { +function observeAsStream(keyPath) { + return _rxjsBundlesRxMinJs.Observable.create(observer => { const disposable = observe(keyPath, observer.next.bind(observer)); return disposable.dispose.bind(disposable); }); @@ -91,29 +75,15 @@ function observeAsStream(keyPath: string): Observable { * Takes and returns the same types as `atom.config.onDidChange` except `keyPath` is not optional. * To listen to changes on all key paths, use `atom.config.onDidChange`. */ -function onDidChange( - keyPath: string, - optionsOrCallback: (Object | (event: Object) => void), - callback?: (event: Object) => void, -): IDisposable { - return atom.config.onDidChange( - formatKeyPath(keyPath), - ...Array.prototype.slice.call(arguments, 1), - ); +function onDidChange(keyPath, optionsOrCallback, callback) { + return atom.config.onDidChange(formatKeyPath(keyPath), ...Array.prototype.slice.call(arguments, 1)); } /* * Sets the value of a setting for a Nuclide feature key. Takes and returns the same types as * `atom.config.set`. */ -function set( - keyPath: string, - value: ?mixed, - options?: { - scopeSelector?: string, - source?: string, - }, -): boolean { +function set(keyPath, value, options) { return atom.config.set(formatKeyPath(keyPath), ...Array.prototype.slice.call(arguments, 1)); } @@ -121,27 +91,15 @@ function set( * Sets the schema of a setting for a Nuclide feature key. Takes and returns the same types as * `atom.config.setSchema`. */ -function setSchema( - keyPath: string, - schema: Object, -): void { - return atom.config.setSchema( - formatKeyPath(keyPath), - ...Array.prototype.slice.call(arguments, 1), - ); +function setSchema(keyPath, schema) { + return atom.config.setSchema(formatKeyPath(keyPath), ...Array.prototype.slice.call(arguments, 1)); } /* * Restores a setting for a Nuclide feature key to its default value. Takes and returns the same * types as `atom.config.set`. */ -function unset( - keyPath: string, - options?: { - scopeSelector?: string, - source?: string, - }, -): void { +function unset(keyPath, options) { return atom.config.unset(formatKeyPath(keyPath), ...Array.prototype.slice.call(arguments, 1)); } @@ -149,11 +107,11 @@ function unset( * Returns `true` if the feature with the given name is disabled either directly or because the * 'nuclide' package itself is disabled. */ -function isFeatureDisabled(name: string): boolean { +function isFeatureDisabled(name) { return atom.packages.isPackageDisabled('nuclide') || !atom.config.get(`nuclide.use.${name}`); } -export default { +exports.default = { get, getWithDefaults, getSchema, @@ -163,5 +121,6 @@ export default { set, setSchema, unset, - isFeatureDisabled, + isFeatureDisabled }; +module.exports = exports['default']; \ No newline at end of file diff --git a/pkg/commons-atom/file-type-class.js b/pkg/commons-atom/file-type-class.js index 08c0a8629f..447eb947f1 100644 --- a/pkg/commons-atom/file-type-class.js +++ b/pkg/commons-atom/file-type-class.js @@ -1,3 +1,24 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = fileTypeClass; + +var _fsPlus; + +function _load_fsPlus() { + return _fsPlus = _interopRequireDefault(require('fs-plus')); +} + +var _nuclideUri; + +function _load_nuclideUri() { + return _nuclideUri = _interopRequireDefault(require('../commons-node/nuclideUri')); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,27 +26,22 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * */ -import fs from 'fs-plus'; -import nuclideUri from '../commons-node/nuclideUri'; - -import type {NuclideUri} from '../commons-node/nuclideUri'; - -export default function fileTypeClass(filename: NuclideUri): string { +function fileTypeClass(filename) { let typeClass; - const ext = nuclideUri.extname(filename); + const ext = (_nuclideUri || _load_nuclideUri()).default.extname(filename); - if (fs.isReadmePath(filename)) { + if ((_fsPlus || _load_fsPlus()).default.isReadmePath(filename)) { typeClass = 'icon-book'; - } else if (fs.isCompressedExtension(ext)) { + } else if ((_fsPlus || _load_fsPlus()).default.isCompressedExtension(ext)) { typeClass = 'icon-file-zip'; - } else if (fs.isImageExtension(ext)) { + } else if ((_fsPlus || _load_fsPlus()).default.isImageExtension(ext)) { typeClass = 'icon-file-media'; - } else if (fs.isPdfExtension(ext)) { + } else if ((_fsPlus || _load_fsPlus()).default.isPdfExtension(ext)) { typeClass = 'icon-file-pdf'; - } else if (fs.isBinaryExtension(ext)) { + } else if ((_fsPlus || _load_fsPlus()).default.isBinaryExtension(ext)) { typeClass = 'icon-file-binary'; } else { typeClass = 'icon-file-text'; @@ -33,3 +49,4 @@ export default function fileTypeClass(filename: NuclideUri): string { return typeClass; } +module.exports = exports['default']; \ No newline at end of file diff --git a/pkg/commons-atom/format-enoent-notification.js b/pkg/commons-atom/format-enoent-notification.js index 24db1f46a6..f34fcea5a2 100644 --- a/pkg/commons-atom/format-enoent-notification.js +++ b/pkg/commons-atom/format-enoent-notification.js @@ -1,3 +1,24 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = formatEnoentNotification; + +var _featureConfig; + +function _load_featureConfig() { + return _featureConfig = _interopRequireDefault(require('./featureConfig')); +} + +var _string; + +function _load_string() { + return _string = require('../commons-node/string'); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,34 +26,19 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * */ -import featureConfig from './featureConfig'; -import {maybeToString} from '../commons-node/string'; - -type Options = { - feature: string, - toolName: string, - pathSetting: string, -}; - -type Result = { - message: string, - meta: atom$NotificationOptions, -}; - const capitalize = str => str[0].toUpperCase() + str.substr(1); -export default function formatEnoentNotification(options: Options): Result { - const {feature, toolName, pathSetting} = options; - const schema = featureConfig.getSchema(pathSetting); +function formatEnoentNotification(options) { + const { feature, toolName, pathSetting } = options; + const schema = (_featureConfig || _load_featureConfig()).default.getSchema(pathSetting); const settingTitle = schema.title; const categoryTitle = capitalize(pathSetting.split('.').shift()); - const command: string = (featureConfig.get(pathSetting): any); + const command = (_featureConfig || _load_featureConfig()).default.get(pathSetting); const capitalizedFeature = capitalize(feature); - const description = - `${capitalizedFeature} needs *${toolName}* but Nuclide couldn't find it at \`${command}\`. + const description = `${capitalizedFeature} needs *${toolName}* but Nuclide couldn't find it at \`${command}\`. **Troubleshooting Tips** 1. Make sure that *${toolName}* is installed. Some Nuclide features require tools that aren't @@ -41,14 +47,15 @@ export default function formatEnoentNotification(options: Options): Result { 3. Atom doesn't know about PATH modifications made in your shell config (".bash_profile", ".zshrc", etc.). If *${toolName}* is installed and you can run it successfully from your terminal using the command \`${command}\`, Nuclide may just not be looking in the right place. Update the command by - changing the **${maybeToString(settingTitle)}** setting (under **${categoryTitle}**) on the + changing the **${(0, (_string || _load_string()).maybeToString)(settingTitle)}** setting (under **${categoryTitle}**) on the Nuclide settings page.`; return { message: `Nuclide couldn't find *${toolName}*!`, meta: { dismissable: true, - description, - }, + description + } }; } +module.exports = exports['default']; \ No newline at end of file diff --git a/pkg/commons-atom/go-to-location.js b/pkg/commons-atom/go-to-location.js index e70f8fba93..7bf47fe219 100644 --- a/pkg/commons-atom/go-to-location.js +++ b/pkg/commons-atom/go-to-location.js @@ -1,16 +1,11 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the license found in the LICENSE file in - * the root directory of this source tree. - * - * @flow - */ +'use strict'; -import {Subject} from 'rxjs'; -import type {Observable} from 'rxjs'; -import invariant from 'assert'; +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.goToLocation = undefined; + +var _asyncToGenerator = _interopRequireDefault(require('async-to-generator')); /** * Opens the given file. @@ -36,56 +31,69 @@ import invariant from 'assert'; * following comment above its use: * // eslint-disable-next-line nuclide-internal/atom-apis */ -export async function goToLocation( - file: string, - line?: number, - column?: number, - center?: boolean = true, -): Promise { - // Prefer going to the current editor rather than the leftmost editor. - const currentEditor = atom.workspace.getActiveTextEditor(); - if (currentEditor != null && currentEditor.getPath() === file) { - if (line != null) { - goToLocationInEditor(currentEditor, line, column == null ? 0 : column, center); +let goToLocation = exports.goToLocation = (() => { + var _ref = (0, _asyncToGenerator.default)(function* (file, line, column, center = true) { + // Prefer going to the current editor rather than the leftmost editor. + const currentEditor = atom.workspace.getActiveTextEditor(); + if (currentEditor != null && currentEditor.getPath() === file) { + if (line != null) { + goToLocationInEditor(currentEditor, line, column == null ? 0 : column, center); + } else { + if (!(column == null)) { + throw new Error('goToLocation: Cannot specify just column'); + } + } + return currentEditor; } else { - invariant(column == null, 'goToLocation: Cannot specify just column'); - } - return currentEditor; - } else { - // Obviously, calling goToLocation isn't a viable alternative here :P - // eslint-disable-next-line nuclide-internal/atom-apis - const editor = await atom.workspace.open(file, { - initialLine: line, - initialColumn: column, - searchAllPanes: true, - }); + // Obviously, calling goToLocation isn't a viable alternative here :P + // eslint-disable-next-line nuclide-internal/atom-apis + const editor = yield atom.workspace.open(file, { + initialLine: line, + initialColumn: column, + searchAllPanes: true + }); - if (center && line != null) { - editor.scrollToBufferPosition([line, column], {center: true}); + if (center && line != null) { + editor.scrollToBufferPosition([line, column], { center: true }); + } + return editor; } - return editor; - } -} + }); + + return function goToLocation(_x, _x2, _x3) { + return _ref.apply(this, arguments); + }; +})(); /** + * Copyright (c) 2015-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the license found in the LICENSE file in + * the root directory of this source tree. + * + * + */ + +exports.goToLocationInEditor = goToLocationInEditor; +exports.observeNavigatingEditors = observeNavigatingEditors; -const goToLocationSubject = new Subject(); +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js'); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const goToLocationSubject = new _rxjsBundlesRxMinJs.Subject(); // Scrolls to the given line/column at the given editor // broadcasts the editor instance on an observable (subject) available // through the getGoToLocation -export function goToLocationInEditor( - editor: atom$TextEditor, - line: number, - column: number, - center: boolean = true, -): void { +function goToLocationInEditor(editor, line, column, center = true) { editor.setCursorBufferPosition([line, column]); if (center) { - editor.scrollToBufferPosition([line, column], {center: true}); + editor.scrollToBufferPosition([line, column], { center: true }); } goToLocationSubject.next(editor); } -export function observeNavigatingEditors(): Observable { +function observeNavigatingEditors() { return goToLocationSubject; -} +} \ No newline at end of file diff --git a/pkg/commons-atom/loading-notification.js b/pkg/commons-atom/loading-notification.js index 5c2dd2d73d..f836bbda01 100644 --- a/pkg/commons-atom/loading-notification.js +++ b/pkg/commons-atom/loading-notification.js @@ -1,38 +1,41 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the license found in the LICENSE file in - * the root directory of this source tree. - * - * @flow - */ +'use strict'; -import {triggerAfterWait} from '../commons-node/promise'; +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = loadingNotification; + +var _promise; + +function _load_promise() { + return _promise = require('../commons-node/promise'); +} /** * Displays a loading notification while waiting for a promise. * Waits delayMs before actually showing the notification (to prevent flicker). */ -export default function loadingNotification( - promise: Promise, - message: string, - delayMs: number = 100, - options: Object = {}, -): Promise { +function loadingNotification(promise, message, delayMs = 100, options = {}) { let notif = null; const timeoutFn = () => { - notif = atom.notifications.addInfo(message, { - dismissable: true, - ...options, - }); + notif = atom.notifications.addInfo(message, Object.assign({ + dismissable: true + }, options)); }; const cleanupFn = () => { if (notif) { notif.dismiss(); } }; - return triggerAfterWait( - promise, delayMs, timeoutFn, cleanupFn, - ); -} + return (0, (_promise || _load_promise()).triggerAfterWait)(promise, delayMs, timeoutFn, cleanupFn); +} /** + * Copyright (c) 2015-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the license found in the LICENSE file in + * the root directory of this source tree. + * + * + */ + +module.exports = exports['default']; \ No newline at end of file diff --git a/pkg/commons-atom/mouse-to-position.js b/pkg/commons-atom/mouse-to-position.js index 10887ac956..850f136265 100644 --- a/pkg/commons-atom/mouse-to-position.js +++ b/pkg/commons-atom/mouse-to-position.js @@ -1,25 +1,33 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the license found in the LICENSE file in - * the root directory of this source tree. - * - * @flow - */ +'use strict'; -import invariant from 'assert'; - -export function bufferPositionForMouseEvent( - event: MouseEvent, - editor: ?atom$TextEditor = null, -): atom$Point { +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.bufferPositionForMouseEvent = bufferPositionForMouseEvent; +function bufferPositionForMouseEvent(event, editor = null) { const _editor = editor || atom.workspace.getActiveTextEditor(); - invariant(_editor != null); + + if (!(_editor != null)) { + throw new Error('Invariant violation: "_editor != null"'); + } + const view = atom.views.getView(_editor); const component = view.component; - invariant(component != null); + + if (!(component != null)) { + throw new Error('Invariant violation: "component != null"'); + } // Beware, screenPositionForMouseEvent is not a public api and may change in future versions. + + const screenPosition = component.screenPositionForMouseEvent(event); return _editor.bufferPositionForScreenPosition(screenPosition); -} +} /** + * Copyright (c) 2015-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the license found in the LICENSE file in + * the root directory of this source tree. + * + * + */ \ No newline at end of file diff --git a/pkg/commons-atom/observe-element-dimensions.js b/pkg/commons-atom/observe-element-dimensions.js index 87466e89aa..b6d92bbcbe 100644 --- a/pkg/commons-atom/observe-element-dimensions.js +++ b/pkg/commons-atom/observe-element-dimensions.js @@ -1,14 +1,11 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the license found in the LICENSE file in - * the root directory of this source tree. - * - * @flow - */ +'use strict'; -import {Observable} from 'rxjs'; +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.observeElementDimensions = observeElementDimensions; + +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js'); const observerConfig = { childList: true, @@ -16,33 +13,30 @@ const observerConfig = { characterData: true, subtree: true, attributeOldValue: true, - characterDataOldValue: true, -}; - -export type DOMMeasurements = { - clientHeight: number, - clientWidth: number, - offsetHeight: number, - offsetWidth: number, - scrollHeight: number, - scrollWidth: number, -}; - -function getElementDimensions(node: HTMLElement): DOMMeasurements { + characterDataOldValue: true +}; /** + * Copyright (c) 2015-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the license found in the LICENSE file in + * the root directory of this source tree. + * + * + */ + +function getElementDimensions(node) { return { clientHeight: node.clientHeight, clientWidth: node.clientWidth, offsetHeight: node.offsetHeight, offsetWidth: node.offsetWidth, scrollHeight: node.scrollHeight, - scrollWidth: node.scrollWidth, + scrollWidth: node.scrollWidth }; } -export function observeElementDimensions( - node: HTMLElement, -): Observable { - return Observable.create(observer => { +function observeElementDimensions(node) { + return _rxjsBundlesRxMinJs.Observable.create(observer => { observer.next(getElementDimensions(node)); // eslint-disable-next-line no-undef @@ -61,4 +55,4 @@ export function observeElementDimensions( } return true; }); -} +} \ No newline at end of file diff --git a/pkg/commons-atom/observe-grammar-for-text-editors.js b/pkg/commons-atom/observe-grammar-for-text-editors.js index dbad7e36a2..e01d389e74 100644 --- a/pkg/commons-atom/observe-grammar-for-text-editors.js +++ b/pkg/commons-atom/observe-grammar-for-text-editors.js @@ -1,3 +1,18 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = observeGrammarForTextEditors; + +var _atom = require('atom'); + +var _textEditor; + +function _load_textEditor() { + return _textEditor = require('./text-editor'); +} + /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,42 +20,32 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * */ -import {CompositeDisposable, Emitter} from 'atom'; -import {observeTextEditors} from './text-editor'; - const GRAMMAR_CHANGE_EVENT = 'grammar-change'; /** * A singleton that listens to grammar changes in all text editors. */ class GrammarForTextEditorsListener { - _emitter: Emitter; - _subscriptions: CompositeDisposable; constructor() { - this._emitter = new Emitter(); - this._subscriptions = new CompositeDisposable(); - this._subscriptions.add( - this._emitter, - observeTextEditors(textEditor => { - const grammarSubscription = textEditor.observeGrammar(grammar => { - this._emitter.emit(GRAMMAR_CHANGE_EVENT, textEditor); - }); - const destroySubscription = textEditor.onDidDestroy(() => { - grammarSubscription.dispose(); - destroySubscription.dispose(); - }); - this._subscriptions.add(grammarSubscription, destroySubscription); - }), - ); + this._emitter = new _atom.Emitter(); + this._subscriptions = new _atom.CompositeDisposable(); + this._subscriptions.add(this._emitter, (0, (_textEditor || _load_textEditor()).observeTextEditors)(textEditor => { + const grammarSubscription = textEditor.observeGrammar(grammar => { + this._emitter.emit(GRAMMAR_CHANGE_EVENT, textEditor); + }); + const destroySubscription = textEditor.onDidDestroy(() => { + grammarSubscription.dispose(); + destroySubscription.dispose(); + }); + this._subscriptions.add(grammarSubscription, destroySubscription); + })); } - observeGrammarForTextEditors( - fn: (textEditor: TextEditor, grammar: atom$Grammar) => void, - ): IDisposable { + observeGrammarForTextEditors(fn) { function fnWithGrammar(textEditor) { fn(textEditor, textEditor.getGrammar()); } @@ -51,12 +56,12 @@ class GrammarForTextEditorsListener { return this._emitter.on(GRAMMAR_CHANGE_EVENT, fnWithGrammar); } - dispose(): void { + dispose() { this._subscriptions.dispose(); } } -let grammarForTextEditorsListener: ?GrammarForTextEditorsListener; +let grammarForTextEditorsListener; /** * Use this to perform an action on every text editor with its latest grammar. @@ -64,9 +69,7 @@ let grammarForTextEditorsListener: ?GrammarForTextEditorsListener; * @param fn This is called once for every text editor, and then again every * time it changes to a grammar. */ -export default function observeGrammarForTextEditors( - fn: (textEditor: TextEditor, grammar: atom$Grammar) => void, -): IDisposable { +function observeGrammarForTextEditors(fn) { if (!grammarForTextEditorsListener) { grammarForTextEditorsListener = new GrammarForTextEditorsListener(); } @@ -74,10 +77,11 @@ export default function observeGrammarForTextEditors( } if (atom.inSpecMode()) { - observeGrammarForTextEditors.__reset__ = function() { + observeGrammarForTextEditors.__reset__ = function () { if (grammarForTextEditorsListener) { grammarForTextEditorsListener.dispose(); grammarForTextEditorsListener = null; } }; } +module.exports = exports['default']; \ No newline at end of file diff --git a/pkg/commons-atom/observe-language-text-editors.js b/pkg/commons-atom/observe-language-text-editors.js index a7666ec831..f56e0f7a80 100644 --- a/pkg/commons-atom/observe-language-text-editors.js +++ b/pkg/commons-atom/observe-language-text-editors.js @@ -1,3 +1,20 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = observeLanguageTextEditors; + +var _atom = require('atom'); + +var _observeGrammarForTextEditors; + +function _load_observeGrammarForTextEditors() { + return _observeGrammarForTextEditors = _interopRequireDefault(require('./observe-grammar-for-text-editors')); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,12 +22,9 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * */ -import {CompositeDisposable, Emitter} from 'atom'; -import observeGrammarForTextEditors from './observe-grammar-for-text-editors'; - const START_OBSERVING_TEXT_EDITOR_EVENT = 'start-observing-text-editor'; const STOP_OBSERVING_TEXT_EDITOR_EVENT = 'stop-observing-text-editor'; @@ -21,20 +35,15 @@ const STOP_OBSERVING_TEXT_EDITOR_EVENT = 'stop-observing-text-editor'; * multiple callers observe on text editors with the same grammar scopes. */ class LanguageTextEditorsListener { - _grammarScopes: Set; - _emitter: Emitter; - _observedTextEditors: Set; - _destroySubscriptionsMap: Map; - _grammarSubscription: IDisposable; - constructor(grammarScopes: Set) { + constructor(grammarScopes) { this._grammarScopes = grammarScopes; - this._emitter = new Emitter(); + this._emitter = new _atom.Emitter(); this._observedTextEditors = new Set(); this._destroySubscriptionsMap = new Map(); - this._grammarSubscription = observeGrammarForTextEditors((textEditor, grammar) => { + this._grammarSubscription = (0, (_observeGrammarForTextEditors || _load_observeGrammarForTextEditors()).default)((textEditor, grammar) => { const textEditorHasTheRightGrammar = this._grammarScopes.has(grammar.scopeName); const isTextEditorObserved = this._observedTextEditors.has(textEditor); if (textEditorHasTheRightGrammar && !isTextEditorObserved) { @@ -60,25 +69,18 @@ class LanguageTextEditorsListener { }); } - observeLanguageTextEditors( - fn: (textEditor: TextEditor) => void, - cleanupFn: (textEditor: TextEditor) => void, - ): IDisposable { + observeLanguageTextEditors(fn, cleanupFn) { // The event was already handled before `fn` was added to the emitter, so // we need to call it on all the existing editors. - atom.workspace.getTextEditors() - .filter(textEditor => this._grammarScopes.has(textEditor.getGrammar().scopeName)) - // We wrap `fn` instead of passing it directly to `.forEach` so it only - // gets called with one arg (i.e. it matches the Flow annotation). - .forEach(textEditor => fn(textEditor)); - - return new CompositeDisposable( - this._emitter.on(START_OBSERVING_TEXT_EDITOR_EVENT, fn), - this._emitter.on(STOP_OBSERVING_TEXT_EDITOR_EVENT, cleanupFn), - ); + atom.workspace.getTextEditors().filter(textEditor => this._grammarScopes.has(textEditor.getGrammar().scopeName)) + // We wrap `fn` instead of passing it directly to `.forEach` so it only + // gets called with one arg (i.e. it matches the Flow annotation). + .forEach(textEditor => fn(textEditor)); + + return new _atom.CompositeDisposable(this._emitter.on(START_OBSERVING_TEXT_EDITOR_EVENT, fn), this._emitter.on(STOP_OBSERVING_TEXT_EDITOR_EVENT, cleanupFn)); } - dispose(): void { + dispose() { this._emitter.dispose(); this._observedTextEditors.clear(); this._destroySubscriptionsMap.forEach(subscription => subscription.dispose()); @@ -95,14 +97,11 @@ class LanguageTextEditorsListener { * @param cleanupFn This is called when a text editor no longer matches the * grammars or is destroyed. */ -export default function observeLanguageTextEditors( - grammarScopes: Array, - fn: (textEditor: TextEditor) => void, - cleanupFn?: (textEditor: TextEditor) => void, -): IDisposable { - const subscriptions = new CompositeDisposable(); +function observeLanguageTextEditors(grammarScopes, fn, cleanupFn) { + const subscriptions = new _atom.CompositeDisposable(); const listener = new LanguageTextEditorsListener(new Set(grammarScopes)); subscriptions.add(listener); subscriptions.add(listener.observeLanguageTextEditors(fn, cleanupFn || (() => {}))); return subscriptions; } +module.exports = exports['default']; \ No newline at end of file diff --git a/pkg/commons-atom/on-will-destroy-text-buffer.js b/pkg/commons-atom/on-will-destroy-text-buffer.js index 7d93907886..72185ee479 100644 --- a/pkg/commons-atom/on-will-destroy-text-buffer.js +++ b/pkg/commons-atom/on-will-destroy-text-buffer.js @@ -1,3 +1,16 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = onWillDestroyTextBuffer; + +var _textEditor; + +function _load_textEditor() { + return _textEditor = require('./text-editor'); +} + /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,28 +18,25 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * */ -import invariant from 'assert'; -import {isValidTextEditor} from './text-editor'; - -export default function onWillDestroyTextBuffer( - callback: (buffer: atom$TextBuffer) => mixed, -): IDisposable { - return atom.workspace.onWillDestroyPaneItem(({item}) => { - if (!isValidTextEditor(item)) { +function onWillDestroyTextBuffer(callback) { + return atom.workspace.onWillDestroyPaneItem(({ item }) => { + if (!(0, (_textEditor || _load_textEditor()).isValidTextEditor)(item)) { return; } - const editor: atom$TextEditor = (item: any); + const editor = item; const openBufferCount = editor.getBuffer().refcount; - invariant( - openBufferCount !== 0, - 'The file that is about to be closed should still be open.', - ); + + if (!(openBufferCount !== 0)) { + throw new Error('The file that is about to be closed should still be open.'); + } + if (openBufferCount === 1) { callback(editor.getBuffer()); } }); } +module.exports = exports['default']; \ No newline at end of file diff --git a/pkg/commons-atom/projects.js b/pkg/commons-atom/projects.js index 11e415bd8a..9bb6b4eed9 100644 --- a/pkg/commons-atom/projects.js +++ b/pkg/commons-atom/projects.js @@ -1,3 +1,31 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.__test__ = undefined; +exports.getAtomProjectRelativePath = getAtomProjectRelativePath; +exports.getAtomProjectRootPath = getAtomProjectRootPath; +exports.observeProjectPaths = observeProjectPaths; +exports.onDidAddProjectPath = onDidAddProjectPath; +exports.onDidRemoveProjectPath = onDidRemoveProjectPath; + +var _atom = require('atom'); + +var _nuclideUri; + +function _load_nuclideUri() { + return _nuclideUri = _interopRequireDefault(require('../commons-node/nuclideUri')); +} + +var _singleton; + +function _load_singleton() { + return _singleton = _interopRequireDefault(require('../commons-node/singleton')); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,24 +33,18 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * */ -import type {NuclideUri} from '../commons-node/nuclideUri'; - -import {Emitter, Directory} from 'atom'; -import nuclideUri from '../commons-node/nuclideUri'; -import singleton from '../commons-node/singleton'; - const REMOVE_PROJECT_EVENT = 'did-remove-project'; const ADD_PROJECT_EVENT = 'did-add-project'; const PROJECT_PATH_WATCHER_INSTANCE_KEY = '_nuclide_project_path_watcher'; -function getValidProjectPaths(): Array { +function getValidProjectPaths() { return atom.project.getDirectories().filter(directory => { // If a remote directory path is a local `Directory` instance, the project path // isn't yet ready for consumption. - if (nuclideUri.isRemote(directory.getPath()) && directory instanceof Directory) { + if ((_nuclideUri || _load_nuclideUri()).default.isRemote(directory.getPath()) && directory instanceof _atom.Directory) { return false; } return true; @@ -30,16 +52,14 @@ function getValidProjectPaths(): Array { } class ProjectManager { - _emitter: Emitter; - _projectPaths: Set; constructor() { - this._emitter = new Emitter(); + this._emitter = new _atom.Emitter(); this._projectPaths = new Set(getValidProjectPaths()); atom.project.onDidChangePaths(this._updateProjectPaths.bind(this)); } - _updateProjectPaths(newProjectPaths: Array): void { + _updateProjectPaths(newProjectPaths) { const oldProjectPathSet = this._projectPaths; const newProjectPathSet = new Set(getValidProjectPaths()); for (const oldProjectPath of oldProjectPathSet) { @@ -55,30 +75,27 @@ class ProjectManager { this._projectPaths = newProjectPathSet; } - observeProjectPaths(callback: (projectPath: string) => void): IDisposable { + observeProjectPaths(callback) { for (const projectPath of this._projectPaths) { callback(projectPath); } return this._emitter.on(ADD_PROJECT_EVENT, callback); } - onDidAddProjectPath(callback: (projectPath: string) => void): IDisposable { + onDidAddProjectPath(callback) { return this._emitter.on(ADD_PROJECT_EVENT, callback); } - onDidRemoveProjectPath(callback: (projectPath: string) => void): IDisposable { + onDidRemoveProjectPath(callback) { return this._emitter.on(REMOVE_PROJECT_EVENT, callback); } } -function getProjectManager(): ProjectManager { - return singleton.get( - PROJECT_PATH_WATCHER_INSTANCE_KEY, - () => new ProjectManager(), - ); +function getProjectManager() { + return (_singleton || _load_singleton()).default.get(PROJECT_PATH_WATCHER_INSTANCE_KEY, () => new ProjectManager()); } -export function getAtomProjectRelativePath(path: NuclideUri): ?string { +function getAtomProjectRelativePath(path) { const [projectPath, relativePath] = atom.project.relativizePath(path); if (!projectPath) { return null; @@ -86,23 +103,23 @@ export function getAtomProjectRelativePath(path: NuclideUri): ?string { return relativePath; } -export function getAtomProjectRootPath(path: NuclideUri): ?string { +function getAtomProjectRootPath(path) { const [projectPath] = atom.project.relativizePath(path); return projectPath; } -export function observeProjectPaths(callback: (projectPath: string) => void): IDisposable { +function observeProjectPaths(callback) { return getProjectManager().observeProjectPaths(callback); } -export function onDidAddProjectPath(callback: (projectPath: string) => void): IDisposable { +function onDidAddProjectPath(callback) { return getProjectManager().onDidAddProjectPath(callback); } -export function onDidRemoveProjectPath(callback: (projectPath: string) => void): IDisposable { +function onDidRemoveProjectPath(callback) { return getProjectManager().onDidRemoveProjectPath(callback); } -export const __test__ = { - PROJECT_PATH_WATCHER_INSTANCE_KEY, -}; +const __test__ = exports.__test__ = { + PROJECT_PATH_WATCHER_INSTANCE_KEY +}; \ No newline at end of file diff --git a/pkg/commons-atom/range.js b/pkg/commons-atom/range.js index 84aa73492d..ec4b681eea 100644 --- a/pkg/commons-atom/range.js +++ b/pkg/commons-atom/range.js @@ -1,3 +1,19 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.wordAtPosition = wordAtPosition; +exports.trimRange = trimRange; + +var _atom = require('atom'); + +var _range; + +function _load_range() { + return _range = require('../commons-node/range'); +} + /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,23 +21,16 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * */ -import {Range} from 'atom'; -import {wordAtPositionFromBuffer} from '../commons-node/range'; - -export function wordAtPosition( - editor: atom$TextEditor, - position: atom$PointObject, - wordRegex_: ?RegExp, -): ?{wordMatch: Array, range: atom$Range} { +function wordAtPosition(editor, position, wordRegex_) { let wordRegex = wordRegex_; if (!wordRegex) { wordRegex = editor.getLastCursor().wordRegExp(); } const buffer = editor.getBuffer(); - return wordAtPositionFromBuffer(buffer, position, wordRegex); + return (0, (_range || _load_range()).wordAtPositionFromBuffer)(buffer, position, wordRegex); } /** @@ -35,20 +44,16 @@ export function wordAtPosition( * defaults to first non-whitespace character * @return atom$Range the trimmed range */ -export function trimRange( - editor: atom$TextEditor, - rangeToTrim: atom$Range, - stopRegex: RegExp = /\S/, -): atom$Range { +function trimRange(editor, rangeToTrim, stopRegex = /\S/) { const buffer = editor.getBuffer(); - let {start, end} = rangeToTrim; - buffer.scanInRange(stopRegex, rangeToTrim, ({range, stop}) => { + let { start, end } = rangeToTrim; + buffer.scanInRange(stopRegex, rangeToTrim, ({ range, stop }) => { start = range.start; stop(); }); - buffer.backwardsScanInRange(stopRegex, rangeToTrim, ({range, stop}) => { + buffer.backwardsScanInRange(stopRegex, rangeToTrim, ({ range, stop }) => { end = range.end; stop(); }); - return new Range(start, end); -} + return new _atom.Range(start, end); +} \ No newline at end of file diff --git a/pkg/commons-atom/register-grammar.js b/pkg/commons-atom/register-grammar.js index 444df81024..9c7257fa58 100644 --- a/pkg/commons-atom/register-grammar.js +++ b/pkg/commons-atom/register-grammar.js @@ -1,3 +1,9 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = registerGrammar; /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,7 +11,7 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * */ /** @@ -23,10 +29,7 @@ * the grammar is available. * @return whether the extension was registered or not. */ -export default function registerGrammar( - scopeName: string, - extensions: Array, -): boolean { +function registerGrammar(scopeName, extensions) { let customFileTypes = atom.config.get('core.customFileTypes'); if (customFileTypes == null || typeof customFileTypes !== 'object') { customFileTypes = {}; @@ -53,3 +56,4 @@ export default function registerGrammar( return false; } +module.exports = exports['default']; \ No newline at end of file diff --git a/pkg/commons-atom/renderReactRoot.js b/pkg/commons-atom/renderReactRoot.js index 29d9e4a4f2..61e2e0419a 100644 --- a/pkg/commons-atom/renderReactRoot.js +++ b/pkg/commons-atom/renderReactRoot.js @@ -1,3 +1,24 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.renderReactRoot = renderReactRoot; + +var _reactForAtom = require('react-for-atom'); + +var _ReactMountRootElement; + +function _load_ReactMountRootElement() { + return _ReactMountRootElement = _interopRequireDefault(require('../nuclide-ui/ReactMountRootElement')); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/** + * Create a DOM element and mount the React element in it. It will be unmounted when the node is + * detached. + */ /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,18 +26,11 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * */ -import {React} from 'react-for-atom'; -import ReactMountRootElement from '../nuclide-ui/ReactMountRootElement'; - -/** - * Create a DOM element and mount the React element in it. It will be unmounted when the node is - * detached. - */ -export function renderReactRoot(reactElement: React.Element): HTMLElement { - const element = new ReactMountRootElement(); +function renderReactRoot(reactElement) { + const element = new (_ReactMountRootElement || _load_ReactMountRootElement()).default(); element.setReactElement(reactElement); return element; -} +} \ No newline at end of file diff --git a/pkg/commons-atom/spec/ActiveEditorRegistry-spec.js b/pkg/commons-atom/spec/ActiveEditorRegistry-spec.js deleted file mode 100644 index ebe6422f19..0000000000 --- a/pkg/commons-atom/spec/ActiveEditorRegistry-spec.js +++ /dev/null @@ -1,299 +0,0 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the license found in the LICENSE file in - * the root directory of this source tree. - * - * @flow - */ - -import type { - Config, - EventSources, - ResultFunction, - Result, -} from '../ActiveEditorRegistry'; - -import type {Observable} from 'rxjs'; - -import {Subject} from 'rxjs'; - -import {expectObservableToStartWith} from '../../nuclide-test-helpers'; - -import ActiveEditorRegistry from '../ActiveEditorRegistry'; - -type TestProvider = { - priority: number, - grammarScopes: Array, - updateOnEdit?: boolean, -}; - -describe('ActiveEditorRegistry', () => { - let activeEditorRegistry: ActiveEditorRegistry = (null: any); - - let activeEditors: Subject = (null: any); - let editorChanges: Subject = (null: any); - let editorSaves: Subject = (null: any); - - let resultFunction: ResultFunction = (null: any); - let config: Config = (null: any); - let eventSources: EventSources = (null: any); - - let editor1: atom$TextEditor = (null: any); - let editor2: atom$TextEditor = (null: any); - - let events: Observable> = (null: any); - let eventNames: Observable = (null: any); - - let shouldProviderError: boolean = (null: any); - - function initializeService() { - activeEditorRegistry = new ActiveEditorRegistry( - resultFunction, - config, - eventSources, - ); - - events = activeEditorRegistry.getResultsStream().publishReplay(); - eventNames = events.map(event => event.kind); - events.connect(); - } - - beforeEach(() => { - waitsForPromise(async () => { - activeEditors = new Subject(); - editorChanges = new Subject(); - editorSaves = new Subject(); - shouldProviderError = false; - - resultFunction = jasmine.createSpy().andCallFake(async () => { - if (shouldProviderError) { - throw new Error('baaaaad'); - } - }); - config = {}; - eventSources = { - activeEditors, - changesForEditor: () => editorChanges, - savesForEditor: () => editorSaves, - }; - - initializeService(); - - editor1 = await atom.workspace.open(); - editor2 = await atom.workspace.open(); - }); - }); - - describe('when there is a provider', () => { - let provider: TestProvider = (null: any); - beforeEach(() => { - provider = { - priority: 10, - grammarScopes: ['text.plain.null-grammar'], - }; - activeEditorRegistry.consumeProvider(provider); - }); - - it('should create correct event stream during normal use', () => { - waitsForPromise(async () => { - activeEditors.next(null); - await waitForNextTick(); - - activeEditors.next(editor1); - await waitForNextTick(); - - editorChanges.next(undefined); - await waitForNextTick(); - - activeEditors.next(editor2); - - await expectObservableToStartWith(eventNames, [ - 'not-text-editor', - 'pane-change', - 'result', - 'edit', - 'result', - 'pane-change', - 'result', - ]); - - const fullEvents = await events.take(4).toArray().toPromise(); - expect(fullEvents[1]).toEqual({ - kind: 'pane-change', - editor: editor1, - }); - expect(fullEvents[2]).toEqual({ - kind: 'result', - editor: editor1, - provider, - result: undefined, - }); - expect(fullEvents[3]).toEqual({ - kind: 'edit', - editor: editor1, - }); - }); - }); - - it('should not emit save events when it is configured to respond to edit events', () => { - waitsForPromise(async () => { - activeEditors.next(editor1); - await waitForNextTick(); - - editorChanges.next(undefined); - await waitForNextTick(); - - editorSaves.next(undefined); - await waitForNextTick(); - - await expectObservableToStartWith(eventNames, [ - 'pane-change', - 'result', - 'edit', - 'result', - ]); - }); - }); - - describe('when configured to respond to save events', () => { - beforeEach(() => { - config.updateOnEdit = false; - initializeService(); - // Have to re-add this since the re-initialization kills it - activeEditorRegistry.consumeProvider({ - priority: 10, - grammarScopes: ['text.plain.null-grammar'], - }); - }); - - it('should generate and respond to save events', () => { - waitsForPromise(async () => { - activeEditors.next(editor1); - await waitForNextTick(); - - editorChanges.next(undefined); - await waitForNextTick(); - - editorSaves.next(undefined); - await waitForNextTick(); - - await expectObservableToStartWith(eventNames, [ - 'pane-change', - 'result', - 'save', - 'result', - ]); - - const fullEvents = await events.take(3).toArray().toPromise(); - expect(fullEvents[2]).toEqual({ - kind: 'save', - editor: editor1, - }); - }); - }); - }); - - describe('when given providers with different updateOnEdit settings', () => { - beforeEach(() => { - initializeService(); - // Have to re-add this since the re-initialization kills it - activeEditorRegistry.consumeProvider({ - priority: 10, - grammarScopes: ['text.plain.null-grammar'], - }); - activeEditorRegistry.consumeProvider({ - priority: 10, - grammarScopes: ['source.cpp'], - updateOnEdit: false, - }); - spyOn(editor2, 'getGrammar').andReturn({ - scopeName: 'source.cpp', - }); - }); - - it('should generate and respond to the appropriate event', () => { - waitsForPromise(async () => { - activeEditors.next(editor1); - await waitForNextTick(); - - editorChanges.next(undefined); - await waitForNextTick(); - - editorSaves.next(undefined); - await waitForNextTick(); - - activeEditors.next(editor2); - await waitForNextTick(); - - editorChanges.next(undefined); - await waitForNextTick(); - - editorSaves.next(undefined); - await waitForNextTick(); - - await expectObservableToStartWith(eventNames, [ - 'pane-change', - 'result', - 'edit', - 'result', - 'pane-change', - 'result', - 'save', - 'result', - ]); - }); - }); - }); - - it("should produce the 'provider-error' event when a provider errors", () => { - waitsForPromise(async () => { - shouldProviderError = true; - - activeEditors.next(editor1); - await waitForNextTick(); - - await expectObservableToStartWith(eventNames, [ - 'pane-change', - 'provider-error', - ]); - - expect(await events.elementAt(1).toPromise()).toEqual({ - kind: 'provider-error', - provider, - }); - }); - }); - - it('should immediately query a better provider', () => { - const betterProvider = { - priority: 20, - grammarScopes: ['text.plain.null-grammar'], - }; - - activeEditors.next(editor1); - expect(resultFunction).toHaveBeenCalledWith(provider, editor1); - activeEditorRegistry.consumeProvider(betterProvider); - expect(resultFunction).toHaveBeenCalledWith(betterProvider, editor1); - }); - }); - - describe('when there is no provider', () => { - it("should produce the 'no-provider' result when there is no provider", () => { - waitsForPromise(async () => { - activeEditors.next(editor1); - await waitForNextTick(); - - await expectObservableToStartWith(eventNames, [ - 'pane-change', - 'no-provider', - ]); - }); - }); - }); -}); - -function waitForNextTick(): Promise { - return new Promise(resolve => process.nextTick(resolve)); -} diff --git a/pkg/commons-atom/spec/AutocompleteCacher-spec.js b/pkg/commons-atom/spec/AutocompleteCacher-spec.js deleted file mode 100644 index a26107e999..0000000000 --- a/pkg/commons-atom/spec/AutocompleteCacher-spec.js +++ /dev/null @@ -1,254 +0,0 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the license found in the LICENSE file in - * the root directory of this source tree. - * - * @flow - */ - -import {Point} from 'atom'; - -import {Deferred} from '../../commons-node/promise'; - -import AutocompleteCacher from '../AutocompleteCacher'; - -describe('AutocompleteCacher', () => { - let getSuggestions: JasmineSpy = (null: any); - let updateResults: JasmineSpy = (null: any); - let shouldFilter: JasmineSpy | void = undefined; - let mockedSuggestions: Promise> = (null: any); - let mockedUpdateResults: Array = (null: any); - // returned from the second call - let secondMockedUpdateResults: Array = (null: any); - - let autocompleteCacher: AutocompleteCacher> = (null: any); - - let mockedRequest: atom$AutocompleteRequest = (null: any); - let mockedRequest2: atom$AutocompleteRequest = (null: any); - let mockedRequest3: atom$AutocompleteRequest = (null: any); - - // Denotes a new autocomplete session. Previous results cannot be re-used. - let separateMockedRequest: atom$AutocompleteRequest = (null: any); - - function initializeAutocompleteCacher() { - autocompleteCacher = new AutocompleteCacher(getSuggestions, { - updateResults, - shouldFilter, - }); - } - - beforeEach(() => { - waitsForPromise(async () => { - mockedSuggestions = Promise.resolve([]); - mockedUpdateResults = ['first']; - secondMockedUpdateResults = ['second']; - - mockedRequest = { - editor: await atom.workspace.open(), - bufferPosition: new Point(0, 0), - scopeDescriptor: 'foo', - prefix: '', - activatedManually: false, - }; - - mockedRequest2 = { - ...mockedRequest, - bufferPosition: new Point(0, 1), - prefix: 'b', - }; - - mockedRequest3 = { - ...mockedRequest, - bufferPosition: new Point(0, 2), - prefix: 'ba', - }; - - separateMockedRequest = { - ...mockedRequest, - bufferPosition: new Point(1, 0), - prefix: '', - }; - - getSuggestions = jasmine.createSpy('getSuggestions').andCallFake(() => { - return mockedSuggestions; - }); - let updateResultsCallCount = 0; - updateResults = jasmine.createSpy('updateResults').andCallFake(() => { - let result; - if (updateResultsCallCount > 0) { - result = secondMockedUpdateResults; - } else { - result = mockedUpdateResults; - } - updateResultsCallCount++; - return result; - }); - - initializeAutocompleteCacher(); - }); - }); - - it('should call through on first request', () => { - waitsForPromise(async () => { - const results = await autocompleteCacher.getSuggestions(mockedRequest); - expect(results).toBe(await mockedSuggestions); - expect(getSuggestions).toHaveBeenCalledWith(mockedRequest); - expect(updateResults).not.toHaveBeenCalled(); - }); - }); - - it('should just filter original results on the second request', () => { - waitsForPromise(async () => { - await autocompleteCacher.getSuggestions(mockedRequest); - const secondResults = await autocompleteCacher.getSuggestions(mockedRequest2); - - expect(getSuggestions.callCount).toBe(2); - expect(getSuggestions).toHaveBeenCalledWith(mockedRequest); - - expect(updateResults.callCount).toBe(1); - expect(updateResults).toHaveBeenCalledWith(mockedRequest2, await mockedSuggestions); - - expect(secondResults).toBe(mockedUpdateResults); - }); - }); - - it('should satisfy a second query even if the original has not yet resolved', () => { - waitsForPromise(async () => { - const originalSuggestionDeferred = new Deferred(); - mockedSuggestions = originalSuggestionDeferred.promise; - - // on purpose don't await here. the promise is not resolved until later - const firstResultPromise = autocompleteCacher.getSuggestions(mockedRequest); - - const secondResultPromise = autocompleteCacher.getSuggestions(mockedRequest2); - - expect(getSuggestions.callCount).toBe(2); - expect(getSuggestions).toHaveBeenCalledWith(mockedRequest); - expect(updateResults).not.toHaveBeenCalled(); - - originalSuggestionDeferred.resolve([]); - expect(await firstResultPromise).toBe(await originalSuggestionDeferred.promise); - - expect(updateResults.callCount).toBe(1); - expect(updateResults).toHaveBeenCalledWith(mockedRequest2, await firstResultPromise); - - expect(await secondResultPromise).toBe(mockedUpdateResults); - expect(getSuggestions.callCount).toBe(2); - }); - }); - - it('should satisfy a third query even if the original has not yet resolved', () => { - waitsForPromise(async () => { - const originalSuggestionDeferred = new Deferred(); - mockedSuggestions = originalSuggestionDeferred.promise; - - // on purpose don't await here. the promise is not resolved until later - autocompleteCacher.getSuggestions(mockedRequest); - const secondResult = autocompleteCacher.getSuggestions(mockedRequest2); - const finalResult = autocompleteCacher.getSuggestions(mockedRequest3); - - expect(getSuggestions.callCount).toBe(3); - expect(getSuggestions).toHaveBeenCalledWith(mockedRequest); - expect(updateResults).not.toHaveBeenCalled(); - - originalSuggestionDeferred.resolve([]); - - expect(await secondResult).toBe(mockedUpdateResults); - expect(await finalResult).toBe(secondMockedUpdateResults); - - expect(updateResults.callCount).toBe(2); - expect(updateResults.calls.map(call => call.args)).toEqual([ - [mockedRequest2, await mockedSuggestions], - [mockedRequest3, await mockedSuggestions], - ]); - - expect(getSuggestions.callCount).toBe(3); - }); - }); - - it('should pass a new request through if it cannot filter', () => { - waitsForPromise(async () => { - await autocompleteCacher.getSuggestions(mockedRequest); - const secondResults = await autocompleteCacher.getSuggestions(separateMockedRequest); - - expect(getSuggestions.callCount).toBe(2); - expect(getSuggestions.calls.map(call => call.args)).toEqual([ - [mockedRequest], - [separateMockedRequest], - ]); - - expect(updateResults).not.toHaveBeenCalled(); - - expect(secondResults).toBe(await mockedSuggestions); - }); - }); - - it('should pass a new request through if the first returned null', () => { - waitsForPromise(async () => { - mockedSuggestions = Promise.resolve(null); - await autocompleteCacher.getSuggestions(mockedRequest); - - const secondMockedSuggestion = []; - mockedSuggestions = Promise.resolve(secondMockedSuggestion); - const secondResults = await autocompleteCacher.getSuggestions(mockedRequest2); - - expect(getSuggestions.calls.map(call => call.args)).toEqual([ - [mockedRequest], - [mockedRequest2], - ]); - - expect(updateResults).not.toHaveBeenCalled(); - - expect(secondResults).toBe(secondMockedSuggestion); - }); - }); - - describe('with a custom shouldFilter function', () => { - let shouldFilterResult = false; - beforeEach(() => { - shouldFilter = jasmine.createSpy('shouldFilter').andCallFake(() => shouldFilterResult); - initializeAutocompleteCacher(); - }); - - it('should not filter if not allowed', () => { - waitsForPromise(async () => { - await autocompleteCacher.getSuggestions(mockedRequest); - await autocompleteCacher.getSuggestions(mockedRequest2); - - expect(getSuggestions.callCount).toBe(2); - expect(shouldFilter).toHaveBeenCalledWith(mockedRequest, mockedRequest2); - - expect(updateResults).not.toHaveBeenCalled(); - }); - }); - - it('should filter if allowed', () => { - waitsForPromise(async () => { - shouldFilterResult = true; - await autocompleteCacher.getSuggestions(mockedRequest); - const secondResults = await autocompleteCacher.getSuggestions(mockedRequest2); - - expect(getSuggestions.callCount).toBe(2); - expect(getSuggestions).toHaveBeenCalledWith(mockedRequest); - - expect(updateResults.callCount).toBe(1); - expect(updateResults).toHaveBeenCalledWith(mockedRequest2, await mockedSuggestions); - - expect(secondResults).toBe(mockedUpdateResults); - }); - }); - - it('should check the cursor positions of requests before calling shouldFilter', () => { - waitsForPromise(async () => { - await autocompleteCacher.getSuggestions(mockedRequest); - await autocompleteCacher.getSuggestions(separateMockedRequest); - - expect(getSuggestions.callCount).toBe(2); - expect(shouldFilter).not.toHaveBeenCalled(); - expect(updateResults).not.toHaveBeenCalled(); - }); - }); - }); -}); diff --git a/pkg/commons-atom/spec/ContextMenu-spec.js b/pkg/commons-atom/spec/ContextMenu-spec.js deleted file mode 100644 index d731aeaf8b..0000000000 --- a/pkg/commons-atom/spec/ContextMenu-spec.js +++ /dev/null @@ -1,350 +0,0 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the license found in the LICENSE file in - * the root directory of this source tree. - * - * @flow - */ - -import invariant from 'assert'; - -import ContextMenu from '../ContextMenu'; - -describe('ContextMenu', () => { - const cssSelector = '.nuclide-context-menu-unit-test'; - let div: HTMLDivElement; - let menu; - - beforeEach(() => { - div = document.createElement('div'); - div.className = cssSelector.substring(1); - atom.views.getView(atom.workspace).appendChild(div); - }); - - afterEach(() => { - if (menu != null) { - menu.dispose(); - } - if (div != null) { - invariant(div.parentNode != null); - div.parentNode.removeChild(div); - } - }); - - it('initializes an empty ContextMenu properly', () => { - const options = { - type: 'root', - cssSelector, - }; - menu = new ContextMenu(options); - expect(menu.isEmpty()).toBe(true); - }); - - it('items added to a context menu appear in priority order', () => { - waitsForPromise(async () => { - const options = { - type: 'root', - cssSelector, - }; - menu = new ContextMenu(options); - - menu.addItem({label: 'second'}, 20); - menu.addItem({label: 'first', command: 'nuclide-do-something'}, 10); - menu.addItem({label: 'fourth'}, 40); - menu.addItem({label: 'third'}, 30); - - await waitForNextTick(); - - expect(getTemplateForContextMenu()).toEqual([ - {label: 'first', command: 'nuclide-do-something'}, - {label: 'second'}, - {label: 'third'}, - {label: 'fourth'}, - ]); - }); - }); - - it('can handle a mix of menu and submenu items', () => { - waitsForPromise(async () => { - const options = { - type: 'root', - cssSelector, - }; - menu = new ContextMenu(options); - - menu.addItem({label: 'two'}, 20); - menu.addItem({label: 'one'}, 10); - menu.addItem({label: 'four'}, 40); - menu.addItem({label: 'three'}, 30); - - const submenu = new ContextMenu({ - type: 'submenu', - label: 'sub', - parent: menu, - }); - menu.addSubmenu(submenu, 25); - submenu.addItem({label: 'B'}, 2); - submenu.addItem({label: 'A'}, 1); - submenu.addItem({label: 'C'}, 3); - - await waitForNextTick(); - - expect(getTemplateForContextMenu()).toEqual([ - {label: 'one'}, - {label: 'two'}, - { - label: 'sub', - submenu: [ - {label: 'A'}, - {label: 'B'}, - {label: 'C'}, - ], - }, - {label: 'three'}, - {label: 'four'}, - ]); - }); - }); - - it('dispose() returned for an item can be used to remove a menu item', () => { - waitsForPromise(async () => { - const options = { - type: 'root', - cssSelector, - }; - menu = new ContextMenu(options); - - const disposableForItem = menu.addItem({label: 'two'}, 20); - menu.addItem({label: 'one'}, 10); - menu.addItem({label: 'four'}, 40); - menu.addItem({label: 'three'}, 30); - - const submenu = new ContextMenu({ - type: 'submenu', - label: 'sub', - parent: menu, - }); - const disposableForSubmenu = menu.addSubmenu(submenu, 25); - submenu.addItem({label: 'B'}, 2); - const disposableForSubmenuItem = submenu.addItem({label: 'A'}, 1); - submenu.addItem({label: 'C'}, 3); - - await waitForNextTick(); - expect(getTemplateForContextMenu()).toEqual([ - {label: 'one'}, - {label: 'two'}, - { - label: 'sub', - submenu: [ - {label: 'A'}, - {label: 'B'}, - {label: 'C'}, - ], - }, - {label: 'three'}, - {label: 'four'}, - ]); - - // Note that unlike addItem() or addSubmenu(), invoking dispose() is synchronous. - - disposableForItem.dispose(); - expect(getTemplateForContextMenu()).toEqual([ - {label: 'one'}, - { - label: 'sub', - submenu: [ - {label: 'A'}, - {label: 'B'}, - {label: 'C'}, - ], - }, - {label: 'three'}, - {label: 'four'}, - ]); - - disposableForSubmenuItem.dispose(); - expect(getTemplateForContextMenu()).toEqual([ - {label: 'one'}, - { - label: 'sub', - submenu: [ - {label: 'B'}, - {label: 'C'}, - ], - }, - {label: 'three'}, - {label: 'four'}, - ]); - - disposableForSubmenu.dispose(); - expect(getTemplateForContextMenu()).toEqual([ - {label: 'one'}, - {label: 'three'}, - {label: 'four'}, - ]); - }); - }); - - it('removing all submenu items should result in it being filtered from view', () => { - waitsForPromise(async () => { - const options = { - type: 'root', - cssSelector, - }; - menu = new ContextMenu(options); - - menu.addItem({label: 'two'}, 20); - menu.addItem({label: 'one'}, 10); - menu.addItem({label: 'four'}, 40); - menu.addItem({label: 'three'}, 30); - - const submenu = new ContextMenu({ - type: 'submenu', - label: 'sub', - parent: menu, - }); - menu.addSubmenu(submenu, 25); - const disposableForSubmenuItem1 = submenu.addItem({label: 'A'}, 1); - const disposableForSubmenuItem2 = submenu.addItem({label: 'B'}, 2); - const disposableForSubmenuItem3 = submenu.addItem({label: 'C'}, 3); - - await waitForNextTick(); - - expect(getTemplateForContextMenu()).toEqual([ - {label: 'one'}, - {label: 'two'}, - { - label: 'sub', - submenu: [ - {label: 'A'}, - {label: 'B'}, - {label: 'C'}, - ], - }, - {label: 'three'}, - {label: 'four'}, - ]); - - disposableForSubmenuItem1.dispose(); - disposableForSubmenuItem2.dispose(); - disposableForSubmenuItem3.dispose(); - expect(getTemplateForContextMenu()).toEqual([ - {label: 'one'}, - {label: 'two'}, - {label: 'three'}, - {label: 'four'}, - ]); - - // It should still be possible to add items to the submenu after it has been cleared out. - submenu.addItem({label: 'D'}, 4); - - await waitForNextTick(); - - expect(getTemplateForContextMenu()).toEqual([ - {label: 'one'}, - {label: 'two'}, - { - label: 'sub', - submenu: [ - {label: 'D'}, - ], - }, - {label: 'three'}, - {label: 'four'}, - ]); - }); - }); - - it('.isEmpty()', () => { - const options = { - type: 'root', - cssSelector, - }; - menu = new ContextMenu(options); - expect(menu.isEmpty()).toBe(true); - - const submenu = new ContextMenu({ - type: 'submenu', - label: 'sub', - parent: menu, - }); - const disposableForSubmenu = menu.addSubmenu(submenu, 20); - expect(menu.isEmpty()).toBe(false); - - disposableForSubmenu.dispose(); - expect(menu.isEmpty()).toBe(true); - }); - - it('.dispose() removes all items', () => { - waitsForPromise(async () => { - const options = { - type: 'root', - cssSelector, - }; - menu = new ContextMenu(options); - - menu.addItem({label: 'two'}, 20); - menu.addItem({label: 'one'}, 10); - menu.addItem({label: 'four'}, 40); - menu.addItem({label: 'three'}, 30); - - const submenu = new ContextMenu({ - type: 'submenu', - label: 'sub', - parent: menu, - }); - menu.addSubmenu(submenu, 25); - submenu.addItem({label: 'B'}, 2); - submenu.addItem({label: 'A'}, 1); - submenu.addItem({label: 'C'}, 3); - - await waitForNextTick(); - - expect(getTemplateForContextMenu()).toEqual([ - {label: 'one'}, - {label: 'two'}, - { - label: 'sub', - submenu: [ - {label: 'A'}, - {label: 'B'}, - {label: 'C'}, - ], - }, - {label: 'three'}, - {label: 'four'}, - ]); - - expect(menu.isEmpty()).toBe(false); - menu.dispose(); - expect(menu.isEmpty()).toBe(true); - expect(getTemplateForContextMenu()).toEqual([]); - }); - }); - - function getTemplateForContextMenu(): Array { - // $FlowIgnore: This relies on an non-public API of Atom's ContextMenuManager. - const template: Array = atom.contextMenu.templateForElement(div); - const lastItem = template[template.length - 1]; - // Unfortunately, Atom does not give us a way to exclude the 'Inspect Element' item from - // a custom context menu. For now, we exclude it from the template to reduce noise in our - // unit tests. - if (lastItem.label === 'Inspect Element') { - template.pop(); - } - return template; - } -}); - -/** - * Calls to ContextMenu.addItem() and ContextMenu.addSubmenu() on the same turn of the event loop - * batch up their internal _sort() calls to run at the end of the current event loop. This function - * facilitates waiting for that to happen. - * - * @return Promise that resolves on process.nextTick(). - */ -function waitForNextTick(): Promise { - return new Promise(resolve => process.nextTick(resolve)); -} diff --git a/pkg/commons-atom/spec/LocalStorageJsonTable-spec.js b/pkg/commons-atom/spec/LocalStorageJsonTable-spec.js deleted file mode 100644 index 60686ddd3f..0000000000 --- a/pkg/commons-atom/spec/LocalStorageJsonTable-spec.js +++ /dev/null @@ -1,63 +0,0 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the license found in the LICENSE file in - * the root directory of this source tree. - * - * @flow - */ - -/* global localStorage */ - -import {LocalStorageJsonTable} from '../LocalStorageJsonTable'; - -describe('LocalStorageJsonTable', () => { - it('writes values to localStorage', () => { - spyOn(localStorage, 'setItem'); - const storage = new LocalStorageJsonTable('test'); - storage.setItem('a', true); - expect(localStorage.setItem.calls[0].args) - .toEqual(['test', JSON.stringify([{key: 'a', value: true}])]); - }); - - it('writes multiple values to localStorage', () => { - spyOn(localStorage, 'setItem'); - const storage = new LocalStorageJsonTable('test'); - storage.setItem('a', 1); - storage.setItem('b', 2); - expect(localStorage.setItem.mostRecentCall.args) - .toEqual(['test', JSON.stringify([{key: 'a', value: 1}, {key: 'b', value: 2}])]); - }); - - it('retrieves values from localStorage', () => { - spyOn(localStorage, 'getItem').andReturn(JSON.stringify([{key: 'a', value: true}])); - const storage = new LocalStorageJsonTable('test'); - expect(storage.getItem('a')).toBe(true); - }); - - it('retrieves entries from localStorage', () => { - spyOn(localStorage, 'getItem').andReturn(JSON.stringify([{key: 'a', value: true}])); - const storage = new LocalStorageJsonTable('test'); - expect(storage.getEntries()).toEqual([{key: 'a', value: true}]); - }); - - it('has the correct order when the same key is reused', () => { - spyOn(localStorage, 'setItem'); - const storage = new LocalStorageJsonTable('test'); - storage.setItem('a', 1); - storage.setItem('b', 2); - storage.setItem('a', 1); - expect(localStorage.setItem.mostRecentCall.args) - .toEqual(['test', JSON.stringify([{key: 'b', value: 2}, {key: 'a', value: 1}])]); - }); - - it('doesn\'t call setItem when not necessary', () => { - spyOn(localStorage, 'setItem'); - const storage = new LocalStorageJsonTable('test'); - storage.setItem('a', 1); - storage.setItem('b', 2); - storage.setItem('b', 2); - expect(localStorage.setItem.callCount).toBe(2); - }); -}); diff --git a/pkg/commons-atom/spec/PanelRenderer-spec.js b/pkg/commons-atom/spec/PanelRenderer-spec.js deleted file mode 100644 index 4f19f69349..0000000000 --- a/pkg/commons-atom/spec/PanelRenderer-spec.js +++ /dev/null @@ -1,55 +0,0 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the license found in the LICENSE file in - * the root directory of this source tree. - * - * @flow - */ - -import PanelRenderer from '../PanelRenderer'; -import invariant from 'assert'; - -describe('PanelRenderer', () => { - it('defers item creation', () => { - const createItem = jasmine.createSpy().andReturn({}); - const renderer = new PanelRenderer({location: 'top', createItem}); - expect(createItem).not.toHaveBeenCalled(); - renderer.render({visible: false}); - expect(createItem).not.toHaveBeenCalled(); - renderer.render({visible: true}); - expect(createItem).toHaveBeenCalled(); - renderer.dispose(); - }); - - it('shows and hides the panel', () => { - const createItem = jasmine.createSpy().andReturn({}); - const renderer = new PanelRenderer({location: 'top', createItem}); - renderer.render({visible: true}); - const panel = renderer._panel; - invariant(panel != null); - spyOn(panel, 'show'); - spyOn(panel, 'hide'); - renderer.render({visible: false}); - expect(panel.hide).toHaveBeenCalled(); - renderer.render({visible: true}); - expect(panel.show).toHaveBeenCalled(); - renderer.dispose(); - }); - - it('destroys the item when disposed', () => { - const item = { - createElement: () => document.createElement('div'), - destroy: jasmine.createSpy(), - }; - const createItem = () => item; - const renderer = new PanelRenderer({location: 'top', createItem}); - // Force the creation of the item. - renderer.render({visible: true}); - expect(item.destroy).not.toHaveBeenCalled(); - renderer.dispose(); - expect(item.destroy).toHaveBeenCalled(); - expect(item.destroy.calls.length).toBe(1); - }); -}); diff --git a/pkg/commons-atom/spec/ProviderRegistry-spec.js b/pkg/commons-atom/spec/ProviderRegistry-spec.js deleted file mode 100644 index f840c226d8..0000000000 --- a/pkg/commons-atom/spec/ProviderRegistry-spec.js +++ /dev/null @@ -1,60 +0,0 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the license found in the LICENSE file in - * the root directory of this source tree. - * - * @flow - */ - -import type {Provider} from '../ProviderRegistry'; - -import ProviderRegistry from '../ProviderRegistry'; - -describe('ProviderRegistry', () => { - let providerRegistry: ProviderRegistry = (null: any); - let provider1: Provider = (null: any); - let provider2: Provider = (null: any); - - beforeEach(() => { - providerRegistry = new ProviderRegistry(); - provider1 = { - priority: 10, - grammarScopes: ['foo', 'bar'], - }; - provider2 = { - priority: 9, - grammarScopes: ['bar', 'baz'], - }; - providerRegistry.addProvider(provider1); - providerRegistry.addProvider(provider2); - }); - - it('should return the highest-priority provider', () => { - expect(providerRegistry.findProvider('foo')).toBe(provider1); - expect(providerRegistry.findProvider('bar')).toBe(provider1); - expect(providerRegistry.findProvider('baz')).toBe(provider2); - }); - - it('should return the provider for an editor', () => { - const editor: any = { - getGrammar() { - return { - scopeName: 'foo', - }; - }, - }; - expect(providerRegistry.getProviderForEditor(editor)).toBe(provider1); - }); - - it('should return null if there is no provider', () => { - expect(providerRegistry.findProvider('42')).toBeNull(); - }); - - it('should correctly remove a provider', () => { - providerRegistry.removeProvider(provider1); - expect(providerRegistry.findProvider('foo')).toBe(null); - expect(providerRegistry.findProvider('bar')).toBe(provider2); - }); -}); diff --git a/pkg/commons-atom/spec/browser-cookies.js b/pkg/commons-atom/spec/browser-cookies.js deleted file mode 100644 index c5f9f0f0e8..0000000000 --- a/pkg/commons-atom/spec/browser-cookies.js +++ /dev/null @@ -1,31 +0,0 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the license found in the LICENSE file in - * the root directory of this source tree. - * - * @flow - */ - -import browserCookies from '../browser-cookies'; - -describe('browser', () => { - describe('getCookies', () => { - it('gets cookies for a domain', () => waitsForPromise(async () => { - const cookies = await browserCookies.getCookies('example.com'); - expect(typeof cookies).toBe('object'); - })); - }); - - describe('setCookies', () => { - it('can set cookies for a domain/URL', () => waitsForPromise(async () => { - const now = Date.now().toString(); - const cookiesBefore = await browserCookies.getCookies('example.com'); - expect(cookiesBefore.now).not.toBe(now); - await browserCookies.setCookie('http://example.com', 'example.com', 'now', now); - const cookiesAfter = await browserCookies.getCookies('example.com'); - expect(cookiesAfter.now).toBe(now); - })); - }); -}); diff --git a/pkg/commons-atom/spec/createPackage-spec.js b/pkg/commons-atom/spec/createPackage-spec.js deleted file mode 100644 index 3ca08abea6..0000000000 --- a/pkg/commons-atom/spec/createPackage-spec.js +++ /dev/null @@ -1,84 +0,0 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the license found in the LICENSE file in - * the root directory of this source tree. - * - * @flow - */ - -import createPackage from '../createPackage'; - -describe('createPackage', () => { - it('throws when the activation class contains an `activate()`', () => { - class Activation { - activate() {} - } - expect(() => createPackage(Activation)) - .toThrow( - 'Your activation class contains an "activate" method, but that work should be done in the' - + ' constructor.', - ); - }); - - it('throws when the activation class contains a `deactivate()`', () => { - class Activation { - deactivate() {} - } - expect(() => createPackage(Activation)) - .toThrow( - 'Your activation class contains an "deactivate" method. Please use "dispose" instead.', - ); - }); - - it("calls the activation's `dispose()` when deactivated", () => { - let called = false; - class Activation { - dispose() { - called = true; - } - } - const pkg = createPackage(Activation); - pkg.activate(); - expect(called).toBe(false); - pkg.deactivate(); - expect(called).toBe(true); - }); - - it('proxies methods to the activation instance', () => { - let called = false; - class Activation { - doSomething() { - called = true; - } - } - const pkg = createPackage(Activation); - pkg.activate(); - pkg.doSomething(); - expect(called).toBe(true); - }); - - it("throws if methods are called when the package isn't activated", () => { - let called = false; - class Activation { - doSomething() { - called = true; - } - } - const pkg = createPackage(Activation); - pkg.activate(); - pkg.deactivate(); - expect(() => { pkg.doSomething(); }).toThrow('Package not activated'); - expect(called).toBe(false); - }); - - it('contains methods inherited by the activation class', () => { - class A { - inheritedMethod() {} - } - class B extends A {} - const pkg = createPackage(B); - expect('inheritedMethod' in pkg).toBe(true); - }); -}); diff --git a/pkg/commons-atom/spec/debounced-spec.js b/pkg/commons-atom/spec/debounced-spec.js deleted file mode 100644 index befe35d9ab..0000000000 --- a/pkg/commons-atom/spec/debounced-spec.js +++ /dev/null @@ -1,230 +0,0 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the license found in the LICENSE file in - * the root directory of this source tree. - * - * @flow - */ - -import {Point} from 'atom'; -import {Observable} from 'rxjs'; -import { - editorScrollTopDebounced, - observeActivePaneItemDebounced, - observeActiveEditorsDebounced, - editorChangesDebounced, - observeTextEditorsPositions, -} from '../debounced'; -import {goToLocationInEditor} from '../go-to-location'; - -import {sleep} from '../../commons-node/promise'; - -// Shorter than the default so the tests don't run long. -const DEBOUNCE_INTERVAL = 10; -// Longer than DEBOUNCE_INTERVAL so when we wait for this amount of time, a debounced event will be -// emitted. -const SLEEP_INTERVAL = 15; -// Sleep interval for double the debounce interval. -const SLEEP_INTERVAL_2 = 25; - -// eslint-disable-next-line jasmine/no-disabled-tests -xdescribe('editorScrollTopDebounced', () => { - it('debounces scroll event', () => { - const LINES = 1000; - const mockText = Array(LINES) - .fill('MOCK LINE\n') - .reduce((a, b) => a.concat(b)); - - waitsForPromise(async () => { - const editor = await atom.workspace.open(); - editor.setText(mockText); - - const editorScroll = editorScrollTopDebounced(editor, DEBOUNCE_INTERVAL); - - const eventsPromise = editorScroll - .takeUntil(Observable.of(null).delay(500)) - .toArray() - .toPromise(); - - editor.scrollToBufferPosition(new Point(LINES / 2, 0)); - editor.scrollToBufferPosition(new Point(0, 0)); - editor.scrollToBufferPosition(new Point(LINES - 1, 0)); - editor.scrollToBufferPosition(new Point(LINES / 4, 0)); - - const events = await eventsPromise; - - expect(events.length).toBe(1); - - editor.destroy(); - }); - }); -}); - -// eslint-disable-next-line jasmine/no-disabled-tests -xdescribe('pane item change events', () => { - let pane: atom$Pane = (null: any); - let editor1: atom$TextEditor = (null: any); - let editor2: atom$TextEditor = (null: any); - let editor3: atom$TextEditor = (null: any); - let nonEditor: Object = (null: any); - let activePaneItems: Observable = (null: any); - - beforeEach(() => { - waitsForPromise(async () => { - // Since RX manages to dodge the built-in clock mocking we'll use the real clock for these - // tests :( - jasmine.useRealClock(); - - editor3 = await atom.workspace.open(); - editor2 = await atom.workspace.open(); - editor1 = await atom.workspace.open(); - - pane = atom.workspace.getActivePane(); - nonEditor = { - // Ordinarily we would have to provide an element or register a view, but since we are just - // testing the model here and not actually rendering anything Atom doesn't complain. If - // these tests start failing because Atom can't find a view, look here. - getTitle() { return 'foo'; }, - }; - pane.addItem(nonEditor); - pane.activateItem(editor1); - }); - }); - - describe('observeActivePaneItemDebounced', () => { - beforeEach(() => { - activePaneItems = observeActivePaneItemDebounced(DEBOUNCE_INTERVAL); - }); - - it('should issue an initial item', () => { - waitsForPromise(async () => { - expect( - await activePaneItems - .first() - // Split out an empty observable after waiting 20 ms. - .race(Observable.empty().delay(20)) - .toArray() - .toPromise(), - ).toEqual([editor1]); - }); - }); - - it('should debounce', () => { - waitsForPromise(async () => { - const itemsPromise = activePaneItems - .take(2) - .toArray() - .toPromise(); - - await sleep(SLEEP_INTERVAL); - - pane.activateItem(editor2); - pane.activateItem(editor3); - - expect(await itemsPromise).toEqual([editor1, editor3]); - }); - }); - }); - - describe('observeActiveEditorsDebounced', () => { - let activeEditors: Observable = (null: any); - beforeEach(() => { - activeEditors = observeActiveEditorsDebounced(DEBOUNCE_INTERVAL); - }); - - it('should return null if the item is not an editor', () => { - waitsForPromise(async () => { - const itemsPromise = activeEditors - .take(3) - .toArray() - .toPromise(); - - await sleep(SLEEP_INTERVAL); - pane.activateItem(nonEditor); - - await sleep(SLEEP_INTERVAL); - pane.activateItem(editor2); - - expect(await itemsPromise).toEqual([editor1, null, editor2]); - }); - }); - }); - - describe('observeTextEditorsPositions', () => { - it('cursor moves and non-editors', () => { - waitsForPromise(async () => { - const itemsPromise = observeTextEditorsPositions(DEBOUNCE_INTERVAL, DEBOUNCE_INTERVAL) - .take(5) - .toArray() - .toPromise(); - await sleep(SLEEP_INTERVAL_2); - goToLocationInEditor(editor1, 3, 4); - await sleep(SLEEP_INTERVAL_2); - pane.activateItem(nonEditor); - await sleep(SLEEP_INTERVAL_2); - goToLocationInEditor(editor1, 0, 0); - await sleep(SLEEP_INTERVAL_2); - pane.activateItem(editor2); - await sleep(SLEEP_INTERVAL_2); - goToLocationInEditor(editor1, 3, 4); - await sleep(SLEEP_INTERVAL_2); - goToLocationInEditor(editor2, 1, 1); - await sleep(SLEEP_INTERVAL_2); - - expect(await itemsPromise).toEqual([ - { - editor: editor1, - position: new Point(4, 0), - }, - { - editor: editor1, - position: new Point(3, 4), - }, - null, - { - editor: editor2, - position: new Point(3, 0), - }, - { - editor: editor2, - position: new Point(1, 1), - }, - ]); - }); - }); - }); -}); - -// eslint-disable-next-line jasmine/no-disabled-tests -xdescribe('editorChangesDebounced', () => { - let editor: atom$TextEditor = (null: any); - let editorChanges: Observable = (null: any); - - beforeEach(() => { - waitsForPromise(async () => { - jasmine.useRealClock(); - editor = await atom.workspace.open(); - editorChanges = editorChangesDebounced(editor, DEBOUNCE_INTERVAL); - }); - }); - - it('debounces changes', () => { - waitsForPromise(async () => { - const eventsPromise = editorChanges - .takeUntil( - Observable.of(null).delay(50), - ) - .toArray() - .toPromise(); - - await sleep(SLEEP_INTERVAL); - - editor.insertNewline(); - editor.insertNewline(); - - expect((await eventsPromise).length).toBe(1); - }); - }); -}); diff --git a/pkg/commons-atom/spec/featureConfig-spec.js b/pkg/commons-atom/spec/featureConfig-spec.js deleted file mode 100644 index 47371605d0..0000000000 --- a/pkg/commons-atom/spec/featureConfig-spec.js +++ /dev/null @@ -1,45 +0,0 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the license found in the LICENSE file in - * the root directory of this source tree. - * - * @flow - */ - -import featureConfig from '../featureConfig'; - -describe('main', () => { - it('returns numbers when numbers are set', () => { - featureConfig.set('foobar', 5); - expect(featureConfig.get('foobar')).toEqual(5); - }); - - it('returns booleans when numbers are set', () => { - featureConfig.set('cat', true); - expect(featureConfig.get('cat')).toEqual(true); - }); - - it('passes values to observers on change', () => { - const spy = jasmine.createSpy('spy'); - featureConfig.observe('animal', spy); - featureConfig.set('animal', 'yup'); - expect(spy).toHaveBeenCalled(); - }); - - it('calls callbacks passed to `onDidChange`', () => { - const spy = jasmine.createSpy('willis'); - featureConfig.onDidChange('mars.attacks', spy); - featureConfig.set('mars.attacks', 42); - expect(spy).toHaveBeenCalled(); - }); - - it('resets to defaults with "unset"', () => { - featureConfig.setSchema('purple.pants', {type: 'number', default: 15}); - featureConfig.set('purple.pants', 25); - expect(featureConfig.get('purple.pants')).toEqual(25); - featureConfig.unset('purple.pants'); - expect(featureConfig.get('purple.pants')).toEqual(15); - }); -}); diff --git a/pkg/commons-atom/spec/fixtures/file1.txt b/pkg/commons-atom/spec/fixtures/file1.txt deleted file mode 100644 index c0d0fb45c3..0000000000 --- a/pkg/commons-atom/spec/fixtures/file1.txt +++ /dev/null @@ -1,2 +0,0 @@ -line1 -line2 diff --git a/pkg/commons-atom/spec/fixtures/file2.txt b/pkg/commons-atom/spec/fixtures/file2.txt deleted file mode 100644 index c0d0fb45c3..0000000000 --- a/pkg/commons-atom/spec/fixtures/file2.txt +++ /dev/null @@ -1,2 +0,0 @@ -line1 -line2 diff --git a/pkg/commons-atom/spec/fixtures/mouse-listener-for-text-editor/meow.txt b/pkg/commons-atom/spec/fixtures/mouse-listener-for-text-editor/meow.txt deleted file mode 100644 index 6e01b125f6..0000000000 --- a/pkg/commons-atom/spec/fixtures/mouse-listener-for-text-editor/meow.txt +++ /dev/null @@ -1,2 +0,0 @@ -meow meow -meow meow diff --git a/pkg/commons-atom/spec/format-enoent-notification-spec.js b/pkg/commons-atom/spec/format-enoent-notification-spec.js deleted file mode 100644 index c522000c07..0000000000 --- a/pkg/commons-atom/spec/format-enoent-notification-spec.js +++ /dev/null @@ -1,57 +0,0 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the license found in the LICENSE file in - * the root directory of this source tree. - * - * @flow - */ - -import formatEnoentNotification from '../format-enoent-notification'; -import featureConfig from '../featureConfig'; -import invariant from 'assert'; - -describe('formatEnoentNotification', () => { - let formatted; - - beforeEach(() => { - spyOn(featureConfig, 'getSchema').andReturn({ - title: 'Path to Node Executable', - type: 'string', - default: 'node', - description: 'Absolute path to the node executable on your system.', - }); - spyOn(featureConfig, 'get').andReturn('/path/to/node'); - formatted = formatEnoentNotification({ - feature: 'awesome stuff creation', - toolName: 'node', - pathSetting: 'my-special-package.pathToNode', - }); - }); - - it('formats the message', () => { - invariant(formatted != null); - expect(formatted.message).toBe("Nuclide couldn't find *node*!"); - }); - - it('has a useful intro line', () => { - invariant(formatted != null); - const expected = - "Awesome stuff creation needs *node* but Nuclide couldn't find it at `/path/to/node`"; - invariant(formatted.meta.description != null); - expect(formatted.meta.description.startsWith(expected)).toBe(true); - }); - - it('mentions the setting title in the description', () => { - invariant(formatted != null); - invariant(formatted.meta.description != null); - expect(/Path to Node/.test(formatted.meta.description)).toBe(true); - }); - - it('mentions the setting category in the description', () => { - invariant(formatted != null); - invariant(formatted.meta.description != null); - expect(/My-special-package/.test(formatted.meta.description)).toBe(true); - }); -}); diff --git a/pkg/commons-atom/spec/go-to-location-spec.js b/pkg/commons-atom/spec/go-to-location-spec.js deleted file mode 100644 index 8efe829bbc..0000000000 --- a/pkg/commons-atom/spec/go-to-location-spec.js +++ /dev/null @@ -1,134 +0,0 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the license found in the LICENSE file in - * the root directory of this source tree. - * - * @flow - */ - -import {Point} from 'atom'; - -import nuclideUri from '../../commons-node/nuclideUri'; -import {goToLocation, observeNavigatingEditors} from '../go-to-location'; - -const FILE1_PATH = nuclideUri.join(__dirname, 'fixtures/file1.txt'); -const FILE2_PATH = nuclideUri.join(__dirname, 'fixtures/file2.txt'); - -describe('goToLocation', () => { - beforeEach(() => { - atom.workspace.getTextEditors().forEach(editor => { editor.destroy(); }); - }); - - it('should work with nothing open', () => { - waitsForPromise(async () => { - const editor = await goToLocation(FILE1_PATH); - expect(editor.getPath()).toBe(FILE1_PATH); - expect(atom.workspace.getActiveTextEditor()).toBe(editor); - }); - }); - - it('should open the current file successfully', () => { - waitsForPromise(async () => { - const editor1 = await goToLocation(FILE1_PATH); - const editor2 = await goToLocation(FILE1_PATH); - expect(editor1).toBe(editor2); - expect(editor1.getPath()).toBe(FILE1_PATH); - expect(atom.workspace.getActiveTextEditor()).toBe(editor1); - }); - }); - - it('should re-use the editor for an already-open file', () => { - waitsForPromise(async () => { - const editor1 = await goToLocation(FILE1_PATH); - const editor2 = await goToLocation(FILE2_PATH); - expect(atom.workspace.getActiveTextEditor()).toBe(editor2); - - const editor3 = await goToLocation(FILE1_PATH); - expect(editor1).toBe(editor3); - expect(atom.workspace.getActiveTextEditor()).toBe(editor1); - }); - }); - - it('should search other panes for an editor for this file', () => { - waitsForPromise(async () => { - const editor1 = await atom.workspace.open(FILE1_PATH); - const editor2 = await atom.workspace.open(FILE2_PATH, {split: 'right'}); - expect(atom.workspace.getActiveTextEditor()).toBe(editor2); - expect(atom.workspace.paneForItem(editor1)).not.toBe(atom.workspace.paneForItem(editor2)); - - const editor3 = await goToLocation(FILE1_PATH); - expect(atom.workspace.getActiveTextEditor()).toBe(editor3); - expect(editor3).toBe(editor1); - }); - }); - - it('should correctly set the cursor position when opening a file', () => { - waitsForPromise(async () => { - const editor = await goToLocation(FILE1_PATH, 1, 3); - expect(editor.getCursorBufferPosition()).toEqual(new Point(1, 3)); - }); - }); - - it('should correctly set the cursor position when opening an already-open file', () => { - waitsForPromise(async () => { - const editor1 = await atom.workspace.open(FILE1_PATH); - expect(editor1.getCursorBufferPosition()).toEqual(new Point(0, 0)); - - const editor2 = await goToLocation(FILE1_PATH, 1, 3); - expect(editor2).toBe(editor1); - expect(editor1.getCursorBufferPosition()).toEqual(new Point(1, 3)); - }); - }); - - describe('its effect on observeNavigatingEditors', () => { - let navigatingEditorsArray: Array = (null: any); - let subscription: rxjs$ISubscription = (null: any); - - beforeEach(() => { - navigatingEditorsArray = []; - subscription = observeNavigatingEditors().subscribe(editor => { - navigatingEditorsArray.push(editor); - }); - }); - afterEach(() => { - subscription.unsubscribe(); - }); - - it('should not publish when opening a new file', () => { - waitsForPromise(async () => { - await goToLocation(FILE1_PATH, 1, 2); - expect(navigatingEditorsArray).toEqual([]); - }); - }); - - it('should not publish when opening the current editor with no position', () => { - waitsForPromise(async () => { - await goToLocation(FILE1_PATH); - await goToLocation(FILE1_PATH); - expect(navigatingEditorsArray).toEqual([]); - }); - }); - - it('should publish when opening the current file with a position', () => { - waitsForPromise(async () => { - const editor1 = await goToLocation(FILE1_PATH, 1, 2); - expect(navigatingEditorsArray).toEqual([]); - const editor2 = await goToLocation(FILE1_PATH, 1, 2); - expect(editor2).toBe(editor1); - expect(navigatingEditorsArray).toEqual([editor1]); - expect(editor1.getCursorBufferPosition()).toEqual(new Point(1, 2)); - }); - }); - - it('should not publish when opening a file that is already open but not focused', () => { - waitsForPromise(async () => { - await goToLocation(FILE1_PATH, 1, 2); - await goToLocation(FILE2_PATH, 1, 2); - await goToLocation(FILE1_PATH, 1, 2); - expect(navigatingEditorsArray).toEqual([]); - }); - }); - }); -}); diff --git a/pkg/commons-atom/spec/grammars/java.cson b/pkg/commons-atom/spec/grammars/java.cson deleted file mode 100644 index 0cd2a4fab3..0000000000 --- a/pkg/commons-atom/spec/grammars/java.cson +++ /dev/null @@ -1,8 +0,0 @@ -# From https://github.com/atom/language-java/blob/27154ef235a0dc5a17e23e69d29d88a20eced330/grammars/java.cson -'scopeName': 'source.java' -'name': 'Java' -'fileTypes': [ - 'java' - 'bsh' -] -'patterns': [] diff --git a/pkg/commons-atom/spec/grammars/javascript.cson b/pkg/commons-atom/spec/grammars/javascript.cson deleted file mode 100644 index 5717f1f127..0000000000 --- a/pkg/commons-atom/spec/grammars/javascript.cson +++ /dev/null @@ -1,15 +0,0 @@ -# From https://github.com/atom/language-javascript/blob/861c53f200d5faf2d0bf06c6d405d8d683a2aca0/grammars/javascript.cson -'scopeName': 'source.js' -'fileTypes': [ - 'js' - 'htc' - '_js' - 'es' - 'es6' - 'pjs' - 'xsjs' - 'xsjslib' -] -'firstLineMatch': '^#!.*\\b(node|iojs|JavaScript)' -'name': 'JavaScript' -'patterns': [] diff --git a/pkg/commons-atom/spec/grammars/objective-c.cson b/pkg/commons-atom/spec/grammars/objective-c.cson deleted file mode 100644 index 507f979e58..0000000000 --- a/pkg/commons-atom/spec/grammars/objective-c.cson +++ /dev/null @@ -1,12 +0,0 @@ -# From https://github.com/atom/language-objective-c/blob/a0159d115d89698dec7116793163c86233e38a3a/grammars/objective-c.cson -'scopeName': 'source.objc' -'fileTypes': [ - 'm' - 'h' - 'pch' - 'x' - 'xm' - 'xmi' -] -'name': 'Objective-C' -'patterns': [] diff --git a/pkg/commons-atom/spec/loading-notification-spec.js b/pkg/commons-atom/spec/loading-notification-spec.js deleted file mode 100644 index 6ec2a50c5b..0000000000 --- a/pkg/commons-atom/spec/loading-notification-spec.js +++ /dev/null @@ -1,80 +0,0 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the license found in the LICENSE file in - * the root directory of this source tree. - * - * @flow - */ - -import invariant from 'assert'; -import loadingNotification from '../loading-notification'; - -describe('loadingNotification', () => { - let mockNotif; - beforeEach(() => { - mockNotif = { - dismiss: jasmine.createSpy('dismiss'), - }; - spyOn(atom.notifications, 'addInfo').andReturn(mockNotif); - }); - - it('displays and closes a loading notification', () => { - waitsForPromise(async () => { - const testValue = 1; - const promise = new Promise((resolve, reject) => { - setTimeout(() => resolve(testValue), 10); - }); - const resultPromise = loadingNotification( - promise, - 'test message', - /* delayMs */ 0, - ); - advanceClock(10); - expect(await resultPromise).toEqual(testValue); - expect(atom.notifications.addInfo).toHaveBeenCalled(); - invariant(mockNotif); - expect(mockNotif.dismiss).toHaveBeenCalled(); - }); - }); - - it('displays and closes a loading notification for errors', () => { - waitsForPromise(async () => { - const promise = new Promise((resolve, reject) => { - setTimeout(() => reject(), 10); - }); - try { - const resultPromise = loadingNotification( - promise, - 'test message', - /* delayMs */ 0, - ); - advanceClock(10); - await resultPromise; - } catch (e) {} - expect(atom.notifications.addInfo).toHaveBeenCalled(); - invariant(mockNotif); - expect(mockNotif.dismiss).toHaveBeenCalled(); - }); - }); - - it('does nothing for fast promises', () => { - waitsForPromise(async () => { - const testValue = 1; - const promise = new Promise((resolve, reject) => { - setTimeout(() => resolve(testValue), 1); - }); - const resultPromise = loadingNotification( - promise, - 'test message', - /* delayMs */ 10, - ); - advanceClock(1); - expect(await resultPromise).toEqual(testValue); - expect(atom.notifications.addInfo.calls.length).toEqual(0); - invariant(mockNotif); - expect(mockNotif.dismiss.calls.length).toEqual(0); - }); - }); -}); diff --git a/pkg/commons-atom/spec/observe-grammar-for-text-editors-spec.js b/pkg/commons-atom/spec/observe-grammar-for-text-editors-spec.js deleted file mode 100644 index 038919877a..0000000000 --- a/pkg/commons-atom/spec/observe-grammar-for-text-editors-spec.js +++ /dev/null @@ -1,112 +0,0 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the license found in the LICENSE file in - * the root directory of this source tree. - * - * @flow - */ - -import nullthrows from 'nullthrows'; -import nuclideUri from '../../commons-node/nuclideUri'; -import observeGrammarForTextEditors from '../observe-grammar-for-text-editors'; - -describe('observeGrammarForTextEditors', () => { - let objcGrammar: atom$Grammar = (null: any); - let jsGrammar: atom$Grammar = (null: any); - - beforeEach(() => { - observeGrammarForTextEditors.__reset__(); - // The grammar registry is cleared automatically after Atom 1.3.0+ - atom.grammars.clear(); - atom.grammars.loadGrammarSync(nuclideUri.join(__dirname, 'grammars/objective-c.cson')); - objcGrammar = nullthrows(atom.grammars.grammarForScopeName('source.objc')); - atom.grammars.loadGrammarSync(nuclideUri.join(__dirname, 'grammars/javascript.cson')); - jsGrammar = nullthrows(atom.grammars.grammarForScopeName('source.js')); - }); - - it('calls for existing text editors', () => { - waitsForPromise(async () => { - const textEditor = await atom.workspace.open('file.m'); - - const fn: any = jasmine.createSpy('fn'); - const subscription = observeGrammarForTextEditors(fn); - expect(fn).toHaveBeenCalledWith(textEditor, objcGrammar); - expect(fn.callCount).toBe(1); - - subscription.dispose(); - textEditor.destroy(); - }); - }); - - it('calls for new text editors', () => { - waitsForPromise(async () => { - const fn: any = jasmine.createSpy('fn'); - const subscription = observeGrammarForTextEditors(fn); - const textEditor = await atom.workspace.open('file.m'); - - expect(fn).toHaveBeenCalledWith(textEditor, objcGrammar); - expect(fn.callCount).toBe(1); - - subscription.dispose(); - textEditor.destroy(); - }); - }); - - it('calls when a text editor changes grammars', () => { - waitsForPromise(async () => { - const fn: any = jasmine.createSpy('fn'); - const subscription = observeGrammarForTextEditors(fn); - const textEditor = await atom.workspace.open('file.m'); - textEditor.setGrammar(jsGrammar); - - expect(fn).toHaveBeenCalledWith(textEditor, objcGrammar); - expect(fn).toHaveBeenCalledWith(textEditor, jsGrammar); - expect(fn.callCount).toBe(2); - - subscription.dispose(); - textEditor.destroy(); - }); - }); - - it('does not call after the return value is disposed', () => { - waitsForPromise(async () => { - const fn: any = jasmine.createSpy('fn'); - const subscription = observeGrammarForTextEditors(fn); - const textEditor = await atom.workspace.open('file.m'); - - subscription.dispose(); - textEditor.setGrammar(jsGrammar); - - expect(fn).toHaveBeenCalledWith(textEditor, objcGrammar); - expect(fn.callCount).toBe(1); - - subscription.dispose(); - textEditor.destroy(); - }); - }); - - it('calls for other clients after another listener is disposed', () => { - waitsForPromise(async () => { - const fn: any = jasmine.createSpy('fn'); - const subscription = observeGrammarForTextEditors(fn); - const fn2: any = jasmine.createSpy('fn2'); - const subscription2 = observeGrammarForTextEditors(fn2); - const textEditor = await atom.workspace.open('file.m'); - - subscription.dispose(); - - textEditor.setGrammar(jsGrammar); - - expect(fn).toHaveBeenCalledWith(textEditor, objcGrammar); - expect(fn.callCount).toBe(1); - expect(fn2).toHaveBeenCalledWith(textEditor, objcGrammar); - expect(fn2).toHaveBeenCalledWith(textEditor, jsGrammar); - expect(fn2.callCount).toBe(2); - - subscription2.dispose(); - textEditor.destroy(); - }); - }); -}); diff --git a/pkg/commons-atom/spec/observe-language-text-editors-spec.js b/pkg/commons-atom/spec/observe-language-text-editors-spec.js deleted file mode 100644 index 5ec32e2a59..0000000000 --- a/pkg/commons-atom/spec/observe-language-text-editors-spec.js +++ /dev/null @@ -1,212 +0,0 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the license found in the LICENSE file in - * the root directory of this source tree. - * - * @flow - */ - -import nullthrows from 'nullthrows'; -import nuclideUri from '../../commons-node/nuclideUri'; -import observeGrammarForTextEditors from '../observe-grammar-for-text-editors'; -import observeLanguageTextEditors from '../observe-language-text-editors'; - -describe('observeLanguageTextEditors', () => { - let objcGrammar: atom$Grammar = (null: any); - let javaGrammar: atom$Grammar = (null: any); - let jsGrammar: atom$Grammar = (null: any); - let nullGrammar: atom$Grammar = (null: any); - let grammarScopes: Array = (null: any); - - beforeEach(() => { - observeGrammarForTextEditors.__reset__(); - atom.grammars.loadGrammarSync(nuclideUri.join(__dirname, 'grammars/objective-c.cson')); - objcGrammar = nullthrows(atom.grammars.grammarForScopeName('source.objc')); - - atom.grammars.loadGrammarSync(nuclideUri.join(__dirname, 'grammars/java.cson')); - javaGrammar = nullthrows(atom.grammars.grammarForScopeName('source.java')); - - atom.grammars.loadGrammarSync(nuclideUri.join(__dirname, 'grammars/javascript.cson')); - jsGrammar = nullthrows(atom.grammars.grammarForScopeName('source.js')); - nullGrammar = nullthrows(atom.grammars.grammarForScopeName('text.plain.null-grammar')); - - grammarScopes = [ - objcGrammar.scopeName, - javaGrammar.scopeName, - ]; - }); - - describe('without cleanup function', () => { - it('calls for existing text editors that match the grammars', () => { - waitsForPromise(async () => { - const textEditor = await atom.workspace.open('file.m'); - - const fn: any = jasmine.createSpy('fn'); - const subscription = observeLanguageTextEditors(grammarScopes, fn); - - expect(fn).toHaveBeenCalledWith(textEditor); - expect(fn.callCount).toBe(1); - - subscription.dispose(); - textEditor.destroy(); - }); - }); - - it('calls for new text editors that already match the grammars', () => { - waitsForPromise(async () => { - const fn: any = jasmine.createSpy('fn'); - const subscription = observeLanguageTextEditors(grammarScopes, fn); - - const textEditor = await atom.workspace.open('file.m'); - - expect(fn).toHaveBeenCalledWith(textEditor); - expect(fn.callCount).toBe(1); - - subscription.dispose(); - textEditor.destroy(); - }); - }); - - it('calls for new text editors that change to match the grammars', () => { - waitsForPromise(async () => { - const fn: any = jasmine.createSpy('fn'); - const subscription = observeLanguageTextEditors(grammarScopes, fn); - - const textEditor = await atom.workspace.open(); - textEditor.setGrammar(objcGrammar); - - expect(fn).toHaveBeenCalledWith(textEditor); - expect(fn.callCount).toBe(1); - - subscription.dispose(); - textEditor.destroy(); - }); - }); - - it('does not call for new text editors that change and still don\'t match the grammars', () => { - waitsForPromise(async () => { - const fn: any = jasmine.createSpy('fn'); - const subscription = observeLanguageTextEditors(grammarScopes, fn); - - const textEditor = await atom.workspace.open(); - textEditor.setGrammar(jsGrammar); - - expect(fn.callCount).toBe(0); - - subscription.dispose(); - textEditor.destroy(); - }); - }); - - it('does not call for text editors whose matching grammar changes but still matches', () => { - waitsForPromise(async () => { - const fn: any = jasmine.createSpy('fn'); - const subscription = observeLanguageTextEditors(grammarScopes, fn); - - const textEditor = await atom.workspace.open('file.m'); - textEditor.setGrammar(javaGrammar); - - expect(fn).toHaveBeenCalledWith(textEditor); - expect(fn.callCount).toBe(1); - - subscription.dispose(); - textEditor.destroy(); - }); - }); - - it('stops listening to grammar changes on text editors that are destroyed', () => { - waitsForPromise(async () => { - const fn: any = jasmine.createSpy('fn'); - const subscription = observeLanguageTextEditors(grammarScopes, fn); - - const textEditor = await atom.workspace.open('file.m'); - textEditor.destroy(); - - subscription.dispose(); - }); - }); - }); - - describe('with cleanup function', () => { - it('does not call for existing text editors that do not match the grammars', () => { - waitsForPromise(async () => { - const textEditor = await atom.workspace.open(); - - const fn: any = jasmine.createSpy('fn'); - const cleanupFn: any = jasmine.createSpy('cleanupFn'); - const subscription = observeLanguageTextEditors(grammarScopes, fn, cleanupFn); - - expect(cleanupFn.callCount).toBe(0); - - subscription.dispose(); - textEditor.destroy(); - }); - }); - - it('does not call for new text editors that never matched the grammars', () => { - waitsForPromise(async () => { - const fn: any = jasmine.createSpy('fn'); - const cleanupFn: any = jasmine.createSpy('cleanupFn'); - const subscription = observeLanguageTextEditors(grammarScopes, fn, cleanupFn); - - const textEditor = await atom.workspace.open('file.js'); - textEditor.setGrammar(nullGrammar); - - expect(cleanupFn.callCount).toBe(0); - - subscription.dispose(); - textEditor.destroy(); - }); - }); - - it('calls for new text editors that stop matching the grammars', () => { - waitsForPromise(async () => { - const fn: any = jasmine.createSpy('fn'); - const cleanupFn: any = jasmine.createSpy('cleanupFn'); - const subscription = observeLanguageTextEditors(grammarScopes, fn, cleanupFn); - - const textEditor = await atom.workspace.open('file.m'); - textEditor.setGrammar(nullGrammar); - - expect(cleanupFn).toHaveBeenCalledWith(textEditor); - expect(cleanupFn.callCount).toBe(1); - - subscription.dispose(); - textEditor.destroy(); - }); - }); - - it('does not call when new text editors that do not match the grammars are destroyed', () => { - waitsForPromise(async () => { - const fn: any = jasmine.createSpy('fn'); - const cleanupFn: any = jasmine.createSpy('cleanupFn'); - const subscription = observeLanguageTextEditors(grammarScopes, fn, cleanupFn); - - const textEditor = await atom.workspace.open('file.js'); - textEditor.destroy(); - - expect(cleanupFn.callCount).toBe(0); - - subscription.dispose(); - }); - }); - - it('calls when new text editors matching the grammars are destroyed', () => { - waitsForPromise(async () => { - const fn: any = jasmine.createSpy('fn'); - const cleanupFn: any = jasmine.createSpy('cleanupFn'); - const subscription = observeLanguageTextEditors(grammarScopes, fn, cleanupFn); - - const textEditor = await atom.workspace.open('file.m'); - textEditor.destroy(); - - expect(cleanupFn).toHaveBeenCalledWith(textEditor); - expect(cleanupFn.callCount).toBe(1); - - subscription.dispose(); - }); - }); - }); -}); diff --git a/pkg/commons-atom/spec/projects-spec.js b/pkg/commons-atom/spec/projects-spec.js deleted file mode 100644 index 7aca2bd95d..0000000000 --- a/pkg/commons-atom/spec/projects-spec.js +++ /dev/null @@ -1,58 +0,0 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the license found in the LICENSE file in - * the root directory of this source tree. - * - * @flow - */ - -import temp from 'temp'; -import singleton from '../../commons-node/singleton'; -import * as projects from '../projects'; - -const {PROJECT_PATH_WATCHER_INSTANCE_KEY} = projects.__test__; -let firstProjectPath; -let otherProjectPath; - -describe('projects', () => { - beforeEach(() => { - temp.track(); - // `atom.project.addPath` only works for paths that actually exist. - firstProjectPath = temp.mkdirSync('firstProjectPath'); - otherProjectPath = temp.mkdirSync('otherProjectPath'); - singleton.clear(PROJECT_PATH_WATCHER_INSTANCE_KEY); - atom.project.setPaths([firstProjectPath]); - }); - - describe('observeProjectPaths()', () => { - it('observes existing projects and future added projects', () => { - const projectPaths: Array = []; - projects.observeProjectPaths(projectPath => { projectPaths.push(projectPath); }); - expect(projectPaths).toEqual([firstProjectPath]); - atom.project.addPath(otherProjectPath); - expect(projectPaths).toEqual([firstProjectPath, otherProjectPath]); - }); - }); - - describe('onDidAddProjectPath()', () => { - it('listens only to newly added project paths', () => { - const addedProjectPaths: Array = []; - projects.onDidAddProjectPath(projectPath => { addedProjectPaths.push(projectPath); }); - expect(addedProjectPaths.length).toBe(0); - atom.project.addPath(otherProjectPath); - expect(addedProjectPaths).toEqual([otherProjectPath]); - }); - }); - - describe('onDidRemoveProjectPath()', () => { - it('listens to removed project paths', () => { - const removedProjectPaths: Array = []; - projects.onDidRemoveProjectPath(projectPath => { removedProjectPaths.push(projectPath); }); - expect(removedProjectPaths.length).toBe(0); - atom.project.removePath(firstProjectPath); - expect(removedProjectPaths).toEqual([firstProjectPath]); - }); - }); -}); diff --git a/pkg/commons-atom/spec/register-grammar-spec.js b/pkg/commons-atom/spec/register-grammar-spec.js deleted file mode 100644 index 9db2a886c7..0000000000 --- a/pkg/commons-atom/spec/register-grammar-spec.js +++ /dev/null @@ -1,24 +0,0 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the license found in the LICENSE file in - * the root directory of this source tree. - * - * @flow - */ - -import nuclideUri from '../../commons-node/nuclideUri'; -import registerGrammar from '../register-grammar'; - -describe('registerGrammar', () => { - it('works', () => { - waitsForPromise(async () => { - atom.grammars.loadGrammarSync(nuclideUri.join(__dirname, 'grammars/javascript.cson')); - registerGrammar('source.js', ['cats']); - const textEditor = await atom.workspace.open('file.cats'); - expect(textEditor.getGrammar().scopeName).toBe('source.js'); - textEditor.destroy(); - }); - }); -}); diff --git a/pkg/commons-atom/spec/repositoryContainsPath-spec.js b/pkg/commons-atom/spec/repositoryContainsPath-spec.js deleted file mode 100644 index 8317fbfddf..0000000000 --- a/pkg/commons-atom/spec/repositoryContainsPath-spec.js +++ /dev/null @@ -1,87 +0,0 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the license found in the LICENSE file in - * the root directory of this source tree. - * - * @flow - */ - -import type {HgService as HgServiceType} from '../../nuclide-hg-rpc/lib/HgService'; - -import {Directory, GitRepository} from 'atom'; -import {repositoryContainsPath} from '../../commons-atom/vcs'; -import {checkOutput} from '../../commons-node/process'; -import MockHgService from '../../nuclide-hg-rpc/spec/MockHgService'; -import {HgRepositoryClient} from '../../nuclide-hg-repository-client'; -import nuclideUri from '../../commons-node/nuclideUri'; -import {generateFixture} from '../../nuclide-test-helpers'; - -describe('repositoryContainsPath', () => { - let tempFolder: string = (null: any); - let repoRoot: string = (null: any); - - beforeEach(() => { - // Create a temporary Hg repository. - waitsForPromise(async () => { - tempFolder = await generateFixture('hg-git-bridge', new Map([ - ['repoRoot/file.txt', 'hello world'], - ])); - repoRoot = nuclideUri.join(tempFolder, 'repoRoot'); - }); - }); - - it('is accurate for GitRepository.', () => { - waitsForPromise(async () => { - // Create a temporary Git repository. - await checkOutput('git', ['init'], {cwd: repoRoot}); - - const gitRepository = new GitRepository(repoRoot); - // For some reason, the path returned in tests from - // GitRepository.getWorkingDirectory is prepended with '/private', - // which makes the Directory::contains method inaccurate in - // `repositoryContainsPath`. We mock out the method here to get the - // expected behavior. - spyOn(gitRepository, 'getWorkingDirectory').andCallFake(() => { - return repoRoot; - }); - - expect(repositoryContainsPath(gitRepository, repoRoot)).toBe(true); - const subdir = nuclideUri.join(repoRoot, 'subdir'); - expect(repositoryContainsPath(gitRepository, subdir)).toBe(true); - const parentDir = nuclideUri.resolve(tempFolder, '..'); - expect(repositoryContainsPath(gitRepository, parentDir)).toBe(false); - }); - }); - - it('is accurate for HgRepositoryClient.', () => { - waitsForPromise(async () => { - // Create temporary Hg repository. - await checkOutput('hg', ['init'], {cwd: repoRoot}); - - const mockService = new MockHgService(); - const mockHgService: HgServiceType = (mockService: any); - const hgRepositoryClient = new HgRepositoryClient( - /* repoPath */ - nuclideUri.join(repoRoot, '.hg'), - /* hgService */ - mockHgService, - /* options */ - { - originURL: 'testURL', - workingDirectory: new Directory(repoRoot), - projectRootDirectory: new Directory(repoRoot), - }, - ); - - const hgRepository: atom$Repository = (hgRepositoryClient: any); - - expect(repositoryContainsPath(hgRepository, repoRoot)).toBe(true); - const subdir = nuclideUri.join(repoRoot, 'subdir'); - expect(repositoryContainsPath(hgRepository, subdir)).toBe(true); - const parentDir = nuclideUri.resolve(tempFolder, '..'); - expect(repositoryContainsPath(hgRepository, parentDir)).toBe(false); - }); - }); -}); diff --git a/pkg/commons-atom/spec/testHelpers-spec.js b/pkg/commons-atom/spec/testHelpers-spec.js deleted file mode 100644 index d47ebe0aef..0000000000 --- a/pkg/commons-atom/spec/testHelpers-spec.js +++ /dev/null @@ -1,75 +0,0 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the license found in the LICENSE file in - * the root directory of this source tree. - * - * @flow - */ - -import {Range} from 'atom'; -import { - dispatchKeyboardEvent, - rangeMatchers, -} from '../testHelpers'; - -describe('dispatchKeyboardEvent', () => { - it('sends copy and paste', () => { - waitsForPromise(async () => { - const editor = await atom.workspace.open('file.txt'); - jasmine.attachToDOM(atom.views.getView(atom.workspace)); - editor.insertText('text'); - const events = []; - atom.keymaps.onDidMatchBinding(event => events.push(event)); - - // Copy line. - dispatchKeyboardEvent('c', document.activeElement, {cmd: true}); - // Paste copied line. - dispatchKeyboardEvent('v', document.activeElement, {cmd: true}); - - expect(events.length).toBe(2); - expect(events[0].keystrokes).toBe('cmd-c'); - expect(events[1].keystrokes).toBe('cmd-v'); - expect(editor.getText()).toBe('texttext'); - }); - }); - - it('sends escape', () => { - waitsForPromise(async () => { - await atom.workspace.open('file.txt'); - jasmine.attachToDOM(atom.views.getView(atom.workspace)); - const events = []; - atom.keymaps.onDidMatchBinding(event => events.push(event)); - - // Hit escape key. - dispatchKeyboardEvent('escape', document.activeElement); - - expect(events.length).toBe(1); - expect(events[0].keystrokes).toBe('escape'); - }); - }); -}); - -describe('rangeMatchers', () => { - beforeEach(function() { - this.addMatchers(rangeMatchers); - }); - - describe('toEqualAtomRange', () => { - it('determines when two Ranges are equal.', () => { - expect(new Range([0, 0], [0, 0])).toEqualAtomRange(new Range([0, 0], [0, 0])); - expect(new Range([0, 0], [0, 0])).not.toEqualAtomRange(new Range([1, 0], [0, 0])); - }); - }); - - describe('toEqualAtomRanges', () => { - it('determines when two arrays of Ranges are equal.', () => { - const ranges = [new Range([0, 0], [0, 0]), new Range([1, 1], [1, 1])]; - const sameRanges = [new Range([0, 0], [0, 0]), new Range([1, 1], [1, 1])]; - const differentRanges = [new Range([0, 0], [0, 0]), new Range([2, 2], [2, 2])]; - expect(ranges).toEqualAtomRanges(sameRanges); - expect(ranges).not.toEqualAtomRanges(differentRanges); - }); - }); -}); diff --git a/pkg/commons-atom/spec/text-buffer-spec.js b/pkg/commons-atom/spec/text-buffer-spec.js deleted file mode 100644 index 7cc2a6085d..0000000000 --- a/pkg/commons-atom/spec/text-buffer-spec.js +++ /dev/null @@ -1,60 +0,0 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the license found in the LICENSE file in - * the root directory of this source tree. - * - * @flow - */ - -import { - existingBufferForUri, - bufferForUri, -} from '../text-buffer'; - -describe('existingBufferForUri', () => { - const file1 = '/tmp/file1.txt'; - - it('should open an editor with the same buffer, if previously cached', () => { - const existingBuffer = existingBufferForUri(file1); - expect(existingBuffer).toBeUndefined(); - waitsForPromise(async () => { - const secondFile1Buffer = (await atom.workspace.open(file1)).getBuffer(); - expect(secondFile1Buffer).toBeDefined(); - const bufferAfterCreation = existingBufferForUri(file1); - expect(bufferAfterCreation).toBeDefined(); - }); - }); -}); - -describe('bufferForUri', () => { - const file1 = '/tmp/file1.txt'; - const file2 = '/tmp/file2.txt'; - - let file1Buffer: atom$TextBuffer = (null: any); - - beforeEach(() => { - file1Buffer = bufferForUri(file1); - }); - - it('should open an editor with the same buffer, if previously cached', () => { - waitsForPromise(async () => { - const secondFile1Buffer = (await atom.workspace.open(file1)).getBuffer(); - expect(secondFile1Buffer).toBe(file1Buffer); - }); - }); - - it('should return the same buffer after creating an editor for it', () => { - waitsForPromise(async () => { - const file2Buffer = (await atom.workspace.open(file2)).getBuffer(); - expect(bufferForUri(file2)).toBe(file2Buffer); - }); - }); - - it('should throw an error if remote connection not found', () => { - const uri = 'nuclide://host/abc.txt'; - expect(() => bufferForUri(uri)) - .toThrow(`ServerConnection cannot be found for uri: ${uri}`); - }); -}); diff --git a/pkg/commons-atom/spec/text-editor-spec.js b/pkg/commons-atom/spec/text-editor-spec.js deleted file mode 100644 index 6d047b47aa..0000000000 --- a/pkg/commons-atom/spec/text-editor-spec.js +++ /dev/null @@ -1,63 +0,0 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the license found in the LICENSE file in - * the root directory of this source tree. - * - * @flow - */ - -import { - existingEditorForUri, - observeTextEditors, -} from '../text-editor'; - -describe('existingEditorForUri', () => { - const file1 = '/tmp/file1.txt'; - const file2 = '/tmp/file2.txt'; - const file3 = '/tmp/file3.txt'; - - let file1Editor: atom$TextEditor = (null: any); - let file2Editor: atom$TextEditor = (null: any); - let secondFile2Editor: atom$TextEditor = (null: any); - - beforeEach(() => { - waitsForPromise(async () => { - file1Editor = await atom.workspace.open(file1); - file2Editor = await atom.workspace.open(file2); - secondFile2Editor = await atom.workspace.open(file2); - }); - }); - - it('should find the one editor for a file', () => { - expect(existingEditorForUri(file1)).toBe(file1Editor); - }); - - it('should find one of the editors for a file', () => { - const editor = existingEditorForUri(file2); - expect(editor === file2Editor || editor === secondFile2Editor).toBeTruthy(); - }); - - it('should return null if no editor exists', () => { - expect(existingEditorForUri(file3)).toBeNull(); - }); -}); - -describe('observeTextEditors', () => { - it('should ignore broken remote paths', () => { - waitsForPromise(async () => { - const paths = []; - observeTextEditors(editor => paths.push(editor.getPath())); - - await atom.workspace.open('nuclide:/test'); - await atom.workspace.open(''); - await atom.workspace.open('/tmp/test'); - - expect(paths).toEqual([ - undefined, - '/tmp/test', - ]); - }); - }); -}); diff --git a/pkg/commons-atom/streamProcessToConsoleMessages.js b/pkg/commons-atom/streamProcessToConsoleMessages.js index 9c64891fe3..377524e6a8 100644 --- a/pkg/commons-atom/streamProcessToConsoleMessages.js +++ b/pkg/commons-atom/streamProcessToConsoleMessages.js @@ -1,63 +1,54 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the license found in the LICENSE file in - * the root directory of this source tree. - * - * @flow - */ +'use strict'; -import type {Message} from '../nuclide-console/lib/types'; -import type {ProcessMessage} from '../commons-node/process-rpc-types'; +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.dispatchConsoleToggle = dispatchConsoleToggle; +exports.pipeProcessMessagesToConsole = pipeProcessMessagesToConsole; -import {Subject} from 'rxjs'; +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js'); -export function dispatchConsoleToggle(visible: boolean): void { - atom.commands.dispatch( - atom.views.getView(atom.workspace), - 'nuclide-console:toggle', - {visible}, - ); -} +function dispatchConsoleToggle(visible) { + atom.commands.dispatch(atom.views.getView(atom.workspace), 'nuclide-console:toggle', { visible }); +} /** + * Copyright (c) 2015-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the license found in the LICENSE file in + * the root directory of this source tree. + * + * + */ -export function pipeProcessMessagesToConsole( - processName: string, - progressUpdates: Subject, - processMessage: ProcessMessage, -): void { +function pipeProcessMessagesToConsole(processName, progressUpdates, processMessage) { switch (processMessage.kind) { case 'stderr': - progressUpdates.next({text: processMessage.data, level: 'error'}); + progressUpdates.next({ text: processMessage.data, level: 'error' }); break; case 'stdout': - progressUpdates.next({text: processMessage.data, level: 'info'}); + progressUpdates.next({ text: processMessage.data, level: 'info' }); break; case 'error': - const {error} = processMessage; - progressUpdates.next({text: error.message || String(error), level: 'error'}); + const { error } = processMessage; + progressUpdates.next({ text: error.message || String(error), level: 'error' }); break; case 'exit': if (processMessage.exitCode === 0) { // TODO(asriram) t13831340 Check if console was initially open, if yes then dont close here - progressUpdates.next({text: `${processName} completed successfully`, level: 'success'}); - atom.notifications.addSuccess( - 'Operation completed successfully', { - detail: `${processName} finished`, - }, - ); + progressUpdates.next({ text: `${processName} completed successfully`, level: 'success' }); + atom.notifications.addSuccess('Operation completed successfully', { + detail: `${processName} finished` + }); } else { // Keep console open - progressUpdates.next({text: `${processName} exited with non zero code`, level: 'error'}); - atom.notifications.addError( - 'Operation Failed', { - detail: 'Check console for output', - }, - ); + progressUpdates.next({ text: `${processName} exited with non zero code`, level: 'error' }); + atom.notifications.addError('Operation Failed', { + detail: 'Check console for output' + }); } break; } -} +} \ No newline at end of file diff --git a/pkg/commons-atom/suda-tool-bar.js b/pkg/commons-atom/suda-tool-bar.js index dbcc69e0dd..a726efc43f 100644 --- a/pkg/commons-atom/suda-tool-bar.js +++ b/pkg/commons-atom/suda-tool-bar.js @@ -1,33 +1 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the license found in the LICENSE file in - * the root directory of this source tree. - * - * @flow - */ - -import type {Disposable} from 'atom'; -export type GetToolBar = (group: string) => ToolBarManager; - -type ToolBarManager = { - addButton(options: { - priority?: number, - tooltip?: string, - iconset?: string, - icon?: string, - callback?: string | () => void, - }): ToolBarButtonView, - addSpacer(options: { - priority?: number, - }): ToolBarButtonView, - removeItems(): void, - onDidDestroy(callback: () => void): Disposable, -}; - -type ToolBarButtonView = { - setEnabled(enabled: boolean): void, - destroy(): void, - element: HTMLElement, -}; +'use strict'; \ No newline at end of file diff --git a/pkg/commons-atom/sync-atom-commands.js b/pkg/commons-atom/sync-atom-commands.js index 40c4cf688e..8545e0cbc7 100644 --- a/pkg/commons-atom/sync-atom-commands.js +++ b/pkg/commons-atom/sync-atom-commands.js @@ -1,24 +1,19 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the license found in the LICENSE file in - * the root directory of this source tree. - * - * @flow - */ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = syncAtomCommands; -export type AtomCommands = { - [target: string]: { - [commandName: string]: (event: Event) => mixed, - }, -}; +var _observable; + +function _load_observable() { + return _observable = require('../commons-node/observable'); +} -import {reconcileSets} from '../commons-node/observable'; -import {CompositeDisposable} from 'atom'; -import {Observable} from 'rxjs'; +var _atom = require('atom'); -type Projector = (item: T) => AtomCommands; +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js'); /** * A utility that adds and removes commands to the Atom command registry based on their presence in @@ -26,26 +21,25 @@ type Projector = (item: T) => AtomCommands; * result (commands), we diff the input (sets) since it's easier and less likely to contain * functions (which are unlikely to be able to be safely compared using `===`). */ -export default function syncAtomCommands( - source: Observable>, - project: Projector, - hash?: (v: T) => any, -): IDisposable { +/** + * Copyright (c) 2015-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the license found in the LICENSE file in + * the root directory of this source tree. + * + * + */ + +function syncAtomCommands(source, project, hash) { // Add empty sets before completing and erroring to make sure that we remove remaining commands // in both cases. - const sets = source - .concat(Observable.of(new Set())) - .catch(err => Observable.of(new Set()).concat(Observable.throw(err))); - - return reconcileSets( - sets, - item => { - const commands = project(item); - const disposables = Object.keys(commands).map(target => ( - atom.commands.add(target, commands[target]) - )); - return new CompositeDisposable(...disposables); - }, - hash, - ); + const sets = source.concat(_rxjsBundlesRxMinJs.Observable.of(new Set())).catch(err => _rxjsBundlesRxMinJs.Observable.of(new Set()).concat(_rxjsBundlesRxMinJs.Observable.throw(err))); + + return (0, (_observable || _load_observable()).reconcileSets)(sets, item => { + const commands = project(item); + const disposables = Object.keys(commands).map(target => atom.commands.add(target, commands[target])); + return new _atom.CompositeDisposable(...disposables); + }, hash); } +module.exports = exports['default']; \ No newline at end of file diff --git a/pkg/commons-atom/testHelpers.js b/pkg/commons-atom/testHelpers.js index 3a3c6f6098..af9402e11c 100644 --- a/pkg/commons-atom/testHelpers.js +++ b/pkg/commons-atom/testHelpers.js @@ -1,15 +1,22 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the license found in the LICENSE file in - * the root directory of this source tree. - * - * @flow - */ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.rangeMatchers = undefined; +exports.dispatchKeyboardEvent = dispatchKeyboardEvent; +exports.setLocalProject = setLocalProject; +exports.waitsForFile = waitsForFile; +exports.waitsForFilePosition = waitsForFilePosition; +exports.getMountedReactRootNames = getMountedReactRootNames; -import invariant from 'assert'; -import nuclideUri from '../commons-node/nuclideUri'; +var _nuclideUri; + +function _load_nuclideUri() { + return _nuclideUri = _interopRequireDefault(require('../commons-node/nuclideUri')); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /** * Use this function to simulate keyboard shortcuts or special keys, e.g. cmd-v, @@ -22,21 +29,34 @@ import nuclideUri from '../commons-node/nuclideUri'; * @param metaKeys An object denoting which meta keys are pressed for this * keyboard event. */ -export function dispatchKeyboardEvent( - key: string, - target: ?HTMLElement, - metaKeys: {alt?: boolean, cmd?: boolean, ctrl?: boolean, shift?: boolean} = {}, -): void { - const {alt, cmd, ctrl, shift} = metaKeys; +/** + * Copyright (c) 2015-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the license found in the LICENSE file in + * the root directory of this source tree. + * + * + */ + +function dispatchKeyboardEvent(key, target, metaKeys = {}) { + const { alt, cmd, ctrl, shift } = metaKeys; // Atom requires `key` to be uppercase when `shift` is specified. - invariant(shift !== true || key.toUpperCase() === key); - invariant(target != null); + + if (!(shift !== true || key.toUpperCase() === key)) { + throw new Error('Invariant violation: "shift !== true || key.toUpperCase() === key"'); + } + + if (!(target != null)) { + throw new Error('Invariant violation: "target != null"'); + } + const event = atom.keymaps.constructor.buildKeydownEvent(key, { target, alt: Boolean(alt), cmd: Boolean(cmd), ctrl: Boolean(ctrl), - shift: Boolean(shift), + shift: Boolean(shift) }); atom.keymaps.handleKeyboardEvent(event); } @@ -45,7 +65,7 @@ export function dispatchKeyboardEvent( * Custom matchers for jasmine testing, as described in: * http://jasmine.github.io/1.3/introduction.html#section-Writing_a_custom_matcher. */ -export const rangeMatchers = { +const rangeMatchers = exports.rangeMatchers = { /** * Determines if two Ranges are equal. This function should not be called * directly, but rather added as a Jasmine custom matcher. @@ -53,7 +73,7 @@ export const rangeMatchers = { * @this A JasmineMatcher object. * @returns True if the Ranges are equal. */ - toEqualAtomRange(expected: ?atom$Range): boolean { + toEqualAtomRange(expected) { return Boolean(this.actual && expected && this.actual.isEqual(expected)); }, @@ -64,13 +84,17 @@ export const rangeMatchers = { * @this A JasmineMatcher object. * @returns True if the array of Ranges are equal. */ - toEqualAtomRanges(expected: ?Array): boolean { + toEqualAtomRanges(expected) { let allEqual = true; if (!this.actual || !expected) { return false; } this.actual.some((range, index) => { - invariant(expected); // Tell Flow this is definitely non-null now. + if (!expected) { + throw new Error('Invariant violation: "expected"'); + } // Tell Flow this is definitely non-null now. + + if (range.isEqual(expected[index])) { return false; } else { @@ -79,14 +103,14 @@ export const rangeMatchers = { } }); return allEqual; - }, + } }; /** * Set the project. If there are one or more projects set previously, this * replaces them all with the one(s) provided as the argument `projectPath`. */ -export function setLocalProject(projectPath: string | Array): void { +function setLocalProject(projectPath) { if (Array.isArray(projectPath)) { atom.project.setPaths(projectPath); } else { @@ -98,7 +122,7 @@ export function setLocalProject(projectPath: string | Array): void { * Waits for the specified file to become the active text editor. * Can only be used in a Jasmine context. */ -export function waitsForFile(filename: string, timeoutMs: number = 10000): void { +function waitsForFile(filename, timeoutMs = 10000) { waitsFor(`${filename} to become active`, timeoutMs, () => { const editor = atom.workspace.getActiveTextEditor(); if (editor == null) { @@ -108,16 +132,11 @@ export function waitsForFile(filename: string, timeoutMs: number = 10000): void if (editorPath == null) { return false; } - return nuclideUri.basename(editorPath) === filename; + return (_nuclideUri || _load_nuclideUri()).default.basename(editorPath) === filename; }); } -export function waitsForFilePosition( - filename: string, - row: number, - column: number, - timeoutMs: number = 10000, -): void { +function waitsForFilePosition(filename, row, column, timeoutMs = 10000) { waitsFor(`${filename} to become active at ${row}:${column}`, timeoutMs, () => { const editor = atom.workspace.getActiveTextEditor(); if (editor == null) { @@ -128,9 +147,7 @@ export function waitsForFilePosition( return false; } const pos = editor.getCursorBufferPosition(); - return nuclideUri.basename(editorPath) === filename - && pos.row === row - && pos.column === column; + return (_nuclideUri || _load_nuclideUri()).default.basename(editorPath) === filename && pos.row === row && pos.column === column; }); } @@ -154,16 +171,16 @@ export function waitsForFilePosition( * console.log(ReactComponentTreeHook.getElement(rootID)); * }); */ -export function getMountedReactRootNames(): Array { - const ReactComponentTreeHookPath = - Object.keys(require.cache).find(x => x.endsWith('react/lib/ReactComponentTreeHook.js')); - invariant( - ReactComponentTreeHookPath != null, - 'ReactComponentTreeHook could not be found in the module cache.', - ); +function getMountedReactRootNames() { + const ReactComponentTreeHookPath = Object.keys(require.cache).find(x => x.endsWith('react/lib/ReactComponentTreeHook.js')); + + if (!(ReactComponentTreeHookPath != null)) { + throw new Error('ReactComponentTreeHook could not be found in the module cache.'); + } + const ReactComponentTreeHook = require.cache[ReactComponentTreeHookPath].exports; const reactRootNames = ReactComponentTreeHook.getRootIDs().map(rootID => { return ReactComponentTreeHook.getDisplayName(rootID); }); return reactRootNames; -} +} \ No newline at end of file diff --git a/pkg/commons-atom/text-buffer.js b/pkg/commons-atom/text-buffer.js index f76571f518..937e7942f0 100644 --- a/pkg/commons-atom/text-buffer.js +++ b/pkg/commons-atom/text-buffer.js @@ -1,3 +1,72 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.loadBufferForUri = undefined; + +var _asyncToGenerator = _interopRequireDefault(require('async-to-generator')); + +let loadBufferForUri = exports.loadBufferForUri = (() => { + var _ref = (0, _asyncToGenerator.default)(function* (uri) { + let buffer = existingBufferForUri(uri); + if (buffer == null) { + buffer = createBufferForUri(uri); + } + if (buffer.loaded) { + return buffer; + } + try { + yield buffer.load(); + return buffer; + } catch (error) { + atom.project.removeBuffer(buffer); + throw error; + } + }); + + return function loadBufferForUri(_x) { + return _ref.apply(this, arguments); + }; +})(); + +/** + * Returns an existing buffer for that uri, or create one if not existing. + */ + + +exports.observeBuffers = observeBuffers; +exports.observeBufferOpen = observeBufferOpen; +exports.observeBufferCloseOrRename = observeBufferCloseOrRename; +exports.bufferForUri = bufferForUri; +exports.existingBufferForUri = existingBufferForUri; + +var _atom = require('atom'); + +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js'); + +var _nuclideUri; + +function _load_nuclideUri() { + return _nuclideUri = _interopRequireDefault(require('../commons-node/nuclideUri')); +} + +var _event; + +function _load_event() { + return _event = require('../commons-node/event'); +} + +var _nuclideRemoteConnection; + +function _load_nuclideRemoteConnection() { + return _nuclideRemoteConnection = require('../nuclide-remote-connection'); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +// Once https://github.com/atom/atom/pull/12501 is released, switch to +// `atom.project.observeBuffers`. /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,27 +74,13 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * */ -import type {NuclideUri} from '../commons-node/nuclideUri'; - -import {TextBuffer} from 'atom'; -import {Observable} from 'rxjs'; -import invariant from 'assert'; - -import nuclideUri from '../commons-node/nuclideUri'; -import {observableFromSubscribeFunction} from '../commons-node/event'; -import {ServerConnection, NuclideTextBuffer} from '../nuclide-remote-connection'; - -// Once https://github.com/atom/atom/pull/12501 is released, switch to -// `atom.project.observeBuffers`. -export function observeBuffers(observeBuffer: (buffer: atom$TextBuffer) => mixed): IDisposable { - atom.project.getBuffers() - .filter(buffer => !nuclideUri.isBrokenDeserializedUri(buffer.getPath())) - .forEach(observeBuffer); +function observeBuffers(observeBuffer) { + atom.project.getBuffers().filter(buffer => !(_nuclideUri || _load_nuclideUri()).default.isBrokenDeserializedUri(buffer.getPath())).forEach(observeBuffer); return atom.project.onDidAddBuffer(buffer => { - if (!nuclideUri.isBrokenDeserializedUri(buffer.getPath())) { + if (!(_nuclideUri || _load_nuclideUri()).default.isBrokenDeserializedUri(buffer.getPath())) { observeBuffer(buffer); } }); @@ -33,57 +88,28 @@ export function observeBuffers(observeBuffer: (buffer: atom$TextBuffer) => mixed // Observes all buffer opens. // Buffer renames are sent as an open of the new name. -export function observeBufferOpen(): Observable { - return observableFromSubscribeFunction(observeBuffers) - .mergeMap(buffer => { - const end = observableFromSubscribeFunction(buffer.onDidDestroy.bind(buffer)); - const rename = observableFromSubscribeFunction(buffer.onDidChangePath.bind(buffer)) - .map(() => buffer) - .takeUntil(end); - return Observable.of(buffer).concat(rename); - }); +function observeBufferOpen() { + return (0, (_event || _load_event()).observableFromSubscribeFunction)(observeBuffers).mergeMap(buffer => { + const end = (0, (_event || _load_event()).observableFromSubscribeFunction)(buffer.onDidDestroy.bind(buffer)); + const rename = (0, (_event || _load_event()).observableFromSubscribeFunction)(buffer.onDidChangePath.bind(buffer)).map(() => buffer).takeUntil(end); + return _rxjsBundlesRxMinJs.Observable.of(buffer).concat(rename); + }); } // Note that on a rename, the openedPath will be the path of the buffer when the open was sent, // which may not match the current name of the buffer. -export type CloseBufferEvent = { - kind: 'close', - openedPath: ?NuclideUri, - buffer: atom$TextBuffer, -}; + // Fires a single event when the buffer is destroyed or renamed. // Note that on a rename the buffer path will not be the same as the openedPath. -export function observeBufferCloseOrRename(buffer: atom$TextBuffer): Observable { - const openedPath: ?NuclideUri = buffer.getPath(); - const end = observableFromSubscribeFunction(buffer.onDidDestroy.bind(buffer)); - const rename = observableFromSubscribeFunction(buffer.onDidChangePath.bind(buffer)); - return end.merge(rename) - .take(1) - .map(() => ({kind: 'close', buffer, openedPath})); +function observeBufferCloseOrRename(buffer) { + const openedPath = buffer.getPath(); + const end = (0, (_event || _load_event()).observableFromSubscribeFunction)(buffer.onDidDestroy.bind(buffer)); + const rename = (0, (_event || _load_event()).observableFromSubscribeFunction)(buffer.onDidChangePath.bind(buffer)); + return end.merge(rename).take(1).map(() => ({ kind: 'close', buffer, openedPath })); } -export async function loadBufferForUri(uri: NuclideUri): Promise { - let buffer = existingBufferForUri(uri); - if (buffer == null) { - buffer = createBufferForUri(uri); - } - if (buffer.loaded) { - return buffer; - } - try { - await buffer.load(); - return buffer; - } catch (error) { - atom.project.removeBuffer(buffer); - throw error; - } -} - -/** - * Returns an existing buffer for that uri, or create one if not existing. - */ -export function bufferForUri(uri: NuclideUri): atom$TextBuffer { +function bufferForUri(uri) { const buffer = existingBufferForUri(uri); if (buffer != null) { return buffer; @@ -91,25 +117,29 @@ export function bufferForUri(uri: NuclideUri): atom$TextBuffer { return createBufferForUri(uri); } -function createBufferForUri(uri: NuclideUri): atom$TextBuffer { +function createBufferForUri(uri) { let buffer; - if (nuclideUri.isLocal(uri)) { - buffer = new TextBuffer({filePath: uri}); + if ((_nuclideUri || _load_nuclideUri()).default.isLocal(uri)) { + buffer = new _atom.TextBuffer({ filePath: uri }); } else { - const connection = ServerConnection.getForUri(uri); + const connection = (_nuclideRemoteConnection || _load_nuclideRemoteConnection()).ServerConnection.getForUri(uri); if (connection == null) { throw new Error(`ServerConnection cannot be found for uri: ${uri}`); } - buffer = new NuclideTextBuffer(connection, {filePath: uri}); + buffer = new (_nuclideRemoteConnection || _load_nuclideRemoteConnection()).NuclideTextBuffer(connection, { filePath: uri }); } atom.project.addBuffer(buffer); - invariant(buffer); + + if (!buffer) { + throw new Error('Invariant violation: "buffer"'); + } + return buffer; } /** * Returns an exsting buffer for that uri, or null if not existing. */ -export function existingBufferForUri(uri: NuclideUri): ?atom$TextBuffer { +function existingBufferForUri(uri) { return atom.project.findBufferForPath(uri); -} +} \ No newline at end of file diff --git a/pkg/commons-atom/text-editor.js b/pkg/commons-atom/text-editor.js index 3bda44579a..461278a887 100644 --- a/pkg/commons-atom/text-editor.js +++ b/pkg/commons-atom/text-editor.js @@ -1,26 +1,42 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the license found in the LICENSE file in - * the root directory of this source tree. - * - * @flow - */ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.existingEditorForUri = existingEditorForUri; +exports.existingEditorForBuffer = existingEditorForBuffer; +exports.getViewOfEditor = getViewOfEditor; +exports.getScrollTop = getScrollTop; +exports.setScrollTop = setScrollTop; +exports.setPositionAndScroll = setPositionAndScroll; +exports.getCursorPositions = getCursorPositions; +exports.observeEditorDestroy = observeEditorDestroy; +exports.enforceReadOnly = enforceReadOnly; +exports.enforceSoftWrap = enforceSoftWrap; +exports.observeTextEditors = observeTextEditors; +exports.isValidTextEditor = isValidTextEditor; + +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js'); + +var _event; + +function _load_event() { + return _event = require('../commons-node/event'); +} -import type {NuclideUri} from '../commons-node/nuclideUri'; +var _nuclideUri; -import invariant from 'assert'; -import {Observable} from 'rxjs'; +function _load_nuclideUri() { + return _nuclideUri = _interopRequireDefault(require('../commons-node/nuclideUri')); +} -import {observableFromSubscribeFunction} from '../commons-node/event'; -import nuclideUri from '../commons-node/nuclideUri'; +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /** * Returns a text editor that has the given path open, or null if none exists. If there are multiple * text editors for this path, one is chosen arbitrarily. */ -export function existingEditorForUri(path: NuclideUri): ?atom$TextEditor { +function existingEditorForUri(path) { // This isn't ideal but realistically iterating through even a few hundred editors shouldn't be a // real problem. And if you have more than a few hundred you probably have bigger problems. for (const editor of atom.workspace.getTextEditors()) { @@ -36,7 +52,17 @@ export function existingEditorForUri(path: NuclideUri): ?atom$TextEditor { * Returns a text editor that has the given buffer open, or null if none exists. If there are * multiple text editors for this buffer, one is chosen arbitrarily. */ -export function existingEditorForBuffer(buffer: atom$TextBuffer): ?atom$TextEditor { +/** + * Copyright (c) 2015-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the license found in the LICENSE file in + * the root directory of this source tree. + * + * + */ + +function existingEditorForBuffer(buffer) { // This isn't ideal but realistically iterating through even a few hundred editors shouldn't be a // real problem. And if you have more than a few hundred you probably have bigger problems. for (const editor of atom.workspace.getTextEditors()) { @@ -48,15 +74,15 @@ export function existingEditorForBuffer(buffer: atom$TextBuffer): ?atom$TextEdit return null; } -export function getViewOfEditor(editor: atom$TextEditor): atom$TextEditorElement { +function getViewOfEditor(editor) { return atom.views.getView(editor); } -export function getScrollTop(editor: atom$TextEditor): number { +function getScrollTop(editor) { return getViewOfEditor(editor).getScrollTop(); } -export function setScrollTop(editor: atom$TextEditor, scrollTop: number): void { +function setScrollTop(editor, scrollTop) { getViewOfEditor(editor).setScrollTop(scrollTop); } @@ -67,31 +93,25 @@ export function setScrollTop(editor: atom$TextEditor, scrollTop: number): void { * Can be used with editor.getCursorBufferPosition() & getScrollTop() to restore * an editors cursor and scroll. */ -export function setPositionAndScroll( - editor: atom$TextEditor, - position: atom$Point, - scrollTop: number, -): void { - editor.setCursorBufferPosition(position, {autoscroll: false}); +function setPositionAndScroll(editor, position, scrollTop) { + editor.setCursorBufferPosition(position, { autoscroll: false }); setScrollTop(editor, scrollTop); } -export function getCursorPositions(editor: atom$TextEditor): Observable { +function getCursorPositions(editor) { // This will behave strangely in the face of multiple cursors. Consider supporting multiple // cursors in the future. const cursor = editor.getCursors()[0]; - invariant(cursor != null); - return Observable.merge( - Observable.of(cursor.getBufferPosition()), - observableFromSubscribeFunction(cursor.onDidChangePosition.bind(cursor)) - .map(event => event.newBufferPosition), - ); + + if (!(cursor != null)) { + throw new Error('Invariant violation: "cursor != null"'); + } + + return _rxjsBundlesRxMinJs.Observable.merge(_rxjsBundlesRxMinJs.Observable.of(cursor.getBufferPosition()), (0, (_event || _load_event()).observableFromSubscribeFunction)(cursor.onDidChangePosition.bind(cursor)).map(event => event.newBufferPosition)); } -export function observeEditorDestroy(editor: atom$TextEditor): Observable { - return observableFromSubscribeFunction(editor.onDidDestroy.bind(editor)) - .map(event => editor) - .take(1); +function observeEditorDestroy(editor) { + return (0, (_event || _load_event()).observableFromSubscribeFunction)(editor.onDidDestroy.bind(editor)).map(event => editor).take(1); } // As of the introduction of atom.workspace.buildTextEditor(), it is no longer possible to @@ -99,7 +119,7 @@ export function observeEditorDestroy(editor: atom$TextEditor): Observable {}; // Cancel insert events to prevent typing in the text editor and disallow editing (read-only). @@ -117,11 +137,11 @@ export function enforceReadOnly(textEditor: atom$TextEditor): void { passReadOnlyException('append'); passReadOnlyException('setText'); - function passReadOnlyException(functionName: string) { - const buffer: any = textBuffer; + function passReadOnlyException(functionName) { + const buffer = textBuffer; const originalFunction = buffer[functionName]; - buffer[functionName] = function() { + buffer[functionName] = function () { textBuffer.applyChange = originalApplyChange; const result = originalFunction.apply(textBuffer, arguments); textBuffer.applyChange = noop; @@ -133,10 +153,7 @@ export function enforceReadOnly(textEditor: atom$TextEditor): void { // Turn off soft wrap setting for these editors so diffs properly align. // Some text editor register sometimes override the set soft wrapping // after mounting an editor to the workspace - here, that's watched and reset to `false`. -export function enforceSoftWrap( - editor: atom$TextEditor, - enforcedSoftWrap: boolean, -): IDisposable { +function enforceSoftWrap(editor, enforcedSoftWrap) { editor.setSoftWrapped(enforcedSoftWrap); return editor.onDidChangeSoftWrapped(softWrapped => { if (softWrapped !== enforcedSoftWrap) { @@ -154,7 +171,7 @@ export function enforceSoftWrap( * Small wrapper around `atom.workspace.observeTextEditors` that filters out * uninitialized remote editors. Most callers should use this one instead. */ -export function observeTextEditors(callback: (editor: atom$TextEditor) => mixed): IDisposable { +function observeTextEditors(callback) { // The one place where atom.workspace.observeTextEditors needs to be used. // eslint-disable-next-line nuclide-internal/atom-apis return atom.workspace.observeTextEditors(editor => { @@ -167,10 +184,10 @@ export function observeTextEditors(callback: (editor: atom$TextEditor) => mixed) /** * Checks if an object (typically an Atom pane) is a TextEditor with a non-broken path. */ -export function isValidTextEditor(item: mixed): boolean { +function isValidTextEditor(item) { // eslint-disable-next-line nuclide-internal/atom-apis if (atom.workspace.isTextEditor(item)) { - return !nuclideUri.isBrokenDeserializedUri(((item: any): atom$TextEditor).getPath()); + return !(_nuclideUri || _load_nuclideUri()).default.isBrokenDeserializedUri(item.getPath()); } return false; -} +} \ No newline at end of file diff --git a/pkg/commons-atom/ui-tree-path.js b/pkg/commons-atom/ui-tree-path.js index a5b69585ae..1ea029e643 100644 --- a/pkg/commons-atom/ui-tree-path.js +++ b/pkg/commons-atom/ui-tree-path.js @@ -1,3 +1,9 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = uiTreePath; /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,27 +11,25 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * */ const TREE_API_DATA_PATH = 'data-path'; -import invariant from 'assert'; - /** * This shouldn't be used for the `file-tree` as it's replaced by * the `FileTreeContextMenu` API. * This can only be useful for other `ui/tree` usages, like the `DiffViewTree`. */ -export default function uiTreePath( - event: Event | {currentTarget: EventTarget}, -): ?string { +function uiTreePath(event) { // Event target isn't necessarily an HTMLElement, - // but that's guaranteed in the usages here. - const target: HTMLElement = (event.currentTarget: any); - const nameElement = target.hasAttribute(TREE_API_DATA_PATH) - ? target - : target.querySelector(`[${TREE_API_DATA_PATH}]`); - invariant(nameElement != null); + const target = event.currentTarget; + const nameElement = target.hasAttribute(TREE_API_DATA_PATH) ? target : target.querySelector(`[${TREE_API_DATA_PATH}]`); + + if (!(nameElement != null)) { + throw new Error('Invariant violation: "nameElement != null"'); + } + return nameElement.getAttribute(TREE_API_DATA_PATH); } +module.exports = exports['default']; \ No newline at end of file diff --git a/pkg/commons-atom/vcs.js b/pkg/commons-atom/vcs.js index 427170160d..8f555f9238 100644 --- a/pkg/commons-atom/vcs.js +++ b/pkg/commons-atom/vcs.js @@ -1,129 +1,235 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the license found in the LICENSE file in - * the root directory of this source tree. - * - * @flow - */ +'use strict'; -import type {StatusCodeNumberValue} from '../nuclide-hg-rpc/lib/HgService'; -import type {HgRepositoryClient} from '../nuclide-hg-repository-client/lib/HgRepositoryClient'; -import type {IconName} from '../nuclide-ui/types'; -import type {NuclideUri} from '../commons-node/nuclideUri'; - -import {arrayCompact, mapFilter} from '../commons-node/collection'; -import {asyncExecute} from '../commons-node/process'; -import {diffSets} from '../commons-node/observable'; -import {Directory} from 'atom'; -import {getFileSystemServiceByNuclideUri} from '../nuclide-remote-connection'; -import {hgConstants} from '../nuclide-hg-rpc'; -import invariant from 'assert'; -import nuclideUri from '../commons-node/nuclideUri'; -import {Observable} from 'rxjs'; -import {observableFromSubscribeFunction} from '../commons-node/event'; -import {track} from '../nuclide-analytics'; - -type VcsInfo = { - vcs: string, - root: string, -}; - -const {StatusCodeNumber: HgStatusCodeNumber} = hgConstants; -const vcsInfoCache: {[dir: string]: VcsInfo} = {}; - -async function findVcsHelper(dir: string): Promise { - const options = {cwd: dir}; - const hgResult = await asyncExecute('hg', ['root'], options); - if (hgResult.exitCode === 0) { - return { - vcs: 'hg', - root: hgResult.stdout.trim(), - }; - } +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.RevertibleStatusCodes = exports.FileChangeStatusToTextColor = exports.FileChangeStatusToIcon = exports.FileChangeStatusToPrefix = exports.HgStatusToFileChangeStatus = exports.FileChangeStatus = exports.findVcs = undefined; + +var _asyncToGenerator = _interopRequireDefault(require('async-to-generator')); + +let findVcsHelper = (() => { + var _ref = (0, _asyncToGenerator.default)(function* (dir) { + const options = { cwd: dir }; + const hgResult = yield (0, (_process || _load_process()).asyncExecute)('hg', ['root'], options); + if (hgResult.exitCode === 0) { + return { + vcs: 'hg', + root: hgResult.stdout.trim() + }; + } - const gitResult = await asyncExecute('git', ['rev-parse', '--show-toplevel'], options); - if (gitResult.exitCode === 0) { - return { - vcs: 'git', - root: gitResult.stdout.trim(), - }; - } + const gitResult = yield (0, (_process || _load_process()).asyncExecute)('git', ['rev-parse', '--show-toplevel'], options); + if (gitResult.exitCode === 0) { + return { + vcs: 'git', + root: gitResult.stdout.trim() + }; + } - throw new Error('Could not find VCS for: ' + dir); -} + throw new Error('Could not find VCS for: ' + dir); + }); + + return function findVcsHelper(_x) { + return _ref.apply(this, arguments); + }; +})(); /** * For the given source file, find the type of vcs that is managing it as well * as the root directory for the VCS. */ -export async function findVcs(dir: string): Promise { - let vcsInfo = vcsInfoCache[dir]; - if (vcsInfo) { + + +let findVcs = exports.findVcs = (() => { + var _ref2 = (0, _asyncToGenerator.default)(function* (dir) { + let vcsInfo = vcsInfoCache[dir]; + if (vcsInfo) { + return vcsInfo; + } + + vcsInfo = yield findVcsHelper(dir); + vcsInfoCache[dir] = vcsInfo; return vcsInfo; - } + }); + + return function findVcs(_x2) { + return _ref2.apply(this, arguments); + }; +})(); + +let hgActionToPath = (() => { + var _ref5 = (0, _asyncToGenerator.default)(function* (nodePath, actionName, actionDoneMessage, action) { + if (nodePath == null || nodePath.length === 0) { + atom.notifications.addError(`Cannot ${actionName} an empty path!`); + return; + } + const repository = repositoryForPath(nodePath); + if (repository == null || repository.getType() !== 'hg') { + atom.notifications.addError(`Cannot ${actionName} a non-mercurial repository path`); + return; + } + const hgRepository = repository; + try { + yield action(hgRepository); + atom.notifications.addSuccess(`${actionDoneMessage} \`${repository.relativize(nodePath)}\` successfully.`); + } catch (error) { + atom.notifications.addError(`Failed to ${actionName} \`${repository.relativize(nodePath)}\``, { detail: error.message }); + } + }); + + return function hgActionToPath(_x5, _x6, _x7, _x8) { + return _ref5.apply(this, arguments); + }; +})(); + +let deleteFile = (() => { + var _ref6 = (0, _asyncToGenerator.default)(function* (nuclideFilePath) { + const filePath = (_nuclideUri || _load_nuclideUri()).default.getPath(nuclideFilePath); + const fsService = (0, (_nuclideRemoteConnection || _load_nuclideRemoteConnection()).getFileSystemServiceByNuclideUri)(nuclideFilePath); + try { + yield fsService.unlink(filePath); + const repository = repositoryForPath(nuclideFilePath); + if (repository == null || repository.getType() !== 'hg') { + return; + } + yield repository.remove([filePath], true); + } catch (error) { + atom.notifications.addError('Failed to delete file', { + detail: error + }); + } + }); + + return function deleteFile(_x9) { + return _ref6.apply(this, arguments); + }; +})(); + +exports.getDirtyFileChanges = getDirtyFileChanges; +exports.observeStatusChanges = observeStatusChanges; +exports.addPath = addPath; +exports.revertPath = revertPath; +exports.confirmAndRevertPath = confirmAndRevertPath; +exports.getHgRepositories = getHgRepositories; +exports.getHgRepositoryStream = getHgRepositoryStream; +exports.repositoryForPath = repositoryForPath; +exports.repositoryContainsPath = repositoryContainsPath; +exports.filterMultiRootFileChanges = filterMultiRootFileChanges; +exports.getMultiRootFileChanges = getMultiRootFileChanges; +exports.confirmAndDeletePath = confirmAndDeletePath; + +var _collection; + +function _load_collection() { + return _collection = require('../commons-node/collection'); +} + +var _process; + +function _load_process() { + return _process = require('../commons-node/process'); +} + +var _observable; + +function _load_observable() { + return _observable = require('../commons-node/observable'); +} + +var _atom = require('atom'); + +var _nuclideRemoteConnection; + +function _load_nuclideRemoteConnection() { + return _nuclideRemoteConnection = require('../nuclide-remote-connection'); +} + +var _nuclideHgRpc; + +function _load_nuclideHgRpc() { + return _nuclideHgRpc = require('../nuclide-hg-rpc'); +} - vcsInfo = await findVcsHelper(dir); - vcsInfoCache[dir] = vcsInfo; - return vcsInfo; +var _nuclideUri; + +function _load_nuclideUri() { + return _nuclideUri = _interopRequireDefault(require('../commons-node/nuclideUri')); } -export type FileChangeStatusValue = 1 | 2 | 3 | 4 | 5; +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js'); + +var _event; + +function _load_event() { + return _event = require('../commons-node/event'); +} + +var _nuclideAnalytics; + +function _load_nuclideAnalytics() { + return _nuclideAnalytics = require('../nuclide-analytics'); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/** + * Copyright (c) 2015-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the license found in the LICENSE file in + * the root directory of this source tree. + * + * + */ + +const { StatusCodeNumber: HgStatusCodeNumber } = (_nuclideHgRpc || _load_nuclideHgRpc()).hgConstants; +const vcsInfoCache = {}; -export const FileChangeStatus = Object.freeze({ +const FileChangeStatus = exports.FileChangeStatus = Object.freeze({ ADDED: 1, MODIFIED: 2, MISSING: 3, REMOVED: 4, - UNTRACKED: 5, + UNTRACKED: 5 }); -(FileChangeStatus: {[key: string]: FileChangeStatusValue}); +FileChangeStatus; -export const HgStatusToFileChangeStatus - : {[key: StatusCodeNumberValue]: FileChangeStatusValue} = Object.freeze({ - [HgStatusCodeNumber.ADDED]: FileChangeStatus.ADDED, - [HgStatusCodeNumber.MODIFIED]: FileChangeStatus.MODIFIED, - [HgStatusCodeNumber.MISSING]: FileChangeStatus.MISSING, - [HgStatusCodeNumber.REMOVED]: FileChangeStatus.REMOVED, - [HgStatusCodeNumber.UNTRACKED]: FileChangeStatus.UNTRACKED, - }, -); +const HgStatusToFileChangeStatus = exports.HgStatusToFileChangeStatus = Object.freeze({ + [HgStatusCodeNumber.ADDED]: FileChangeStatus.ADDED, + [HgStatusCodeNumber.MODIFIED]: FileChangeStatus.MODIFIED, + [HgStatusCodeNumber.MISSING]: FileChangeStatus.MISSING, + [HgStatusCodeNumber.REMOVED]: FileChangeStatus.REMOVED, + [HgStatusCodeNumber.UNTRACKED]: FileChangeStatus.UNTRACKED +}); -export const FileChangeStatusToPrefix: {[key: FileChangeStatusValue]: string} = Object.freeze({ +const FileChangeStatusToPrefix = exports.FileChangeStatusToPrefix = Object.freeze({ [FileChangeStatus.ADDED]: '[A] ', [FileChangeStatus.MODIFIED]: '[M] ', [FileChangeStatus.MISSING]: '[!] ', [FileChangeStatus.REMOVED]: '[D] ', - [FileChangeStatus.UNTRACKED]: '[?] ', + [FileChangeStatus.UNTRACKED]: '[?] ' }); -export const FileChangeStatusToIcon: {[key: ?FileChangeStatusValue]: IconName} = Object.freeze({ +const FileChangeStatusToIcon = exports.FileChangeStatusToIcon = Object.freeze({ [FileChangeStatus.ADDED]: 'diff-added', [FileChangeStatus.MODIFIED]: 'diff-modified', [FileChangeStatus.MISSING]: 'stop', [FileChangeStatus.REMOVED]: 'diff-removed', - [FileChangeStatus.UNTRACKED]: 'question', + [FileChangeStatus.UNTRACKED]: 'question' }); -export const FileChangeStatusToTextColor: {[key: ?FileChangeStatusValue]: string} = Object.freeze({ +const FileChangeStatusToTextColor = exports.FileChangeStatusToTextColor = Object.freeze({ [FileChangeStatus.ADDED]: 'text-success', [FileChangeStatus.MODIFIED]: 'text-warning', [FileChangeStatus.MISSING]: 'text-error', [FileChangeStatus.REMOVED]: 'text-error', - [FileChangeStatus.UNTRACKED]: 'text-error', + [FileChangeStatus.UNTRACKED]: 'text-error' }); -export const RevertibleStatusCodes = [ - FileChangeStatus.ADDED, - FileChangeStatus.MODIFIED, - FileChangeStatus.REMOVED, -]; +const RevertibleStatusCodes = exports.RevertibleStatusCodes = [FileChangeStatus.ADDED, FileChangeStatus.MODIFIED, FileChangeStatus.REMOVED]; -export function getDirtyFileChanges( - repository: HgRepositoryClient, -): Map { +function getDirtyFileChanges(repository) { const dirtyFileChanges = new Map(); const statuses = repository.getAllPathStatuses(); for (const filePath in statuses) { @@ -136,100 +242,69 @@ export function getDirtyFileChanges( } const UPDATE_STATUS_DEBOUNCE_MS = 50; -export function observeStatusChanges( - repository: HgRepositoryClient, -): Observable> { - return observableFromSubscribeFunction( - repository.onDidChangeStatuses.bind(repository), - ) - .debounceTime(UPDATE_STATUS_DEBOUNCE_MS) - .startWith(null) - .map(() => getDirtyFileChanges(repository)); +function observeStatusChanges(repository) { + return (0, (_event || _load_event()).observableFromSubscribeFunction)(repository.onDidChangeStatuses.bind(repository)).debounceTime(UPDATE_STATUS_DEBOUNCE_MS).startWith(null).map(() => getDirtyFileChanges(repository)); } -export function addPath(nodePath: ?NuclideUri): Promise { - return hgActionToPath( - nodePath, - 'add', - 'Added', - async (hgRepository: HgRepositoryClient) => { - invariant(nodePath); - track('hg-repository-add', {nodePath}); - await hgRepository.addAll([nodePath]); - }, - ); +function addPath(nodePath) { + return hgActionToPath(nodePath, 'add', 'Added', (() => { + var _ref3 = (0, _asyncToGenerator.default)(function* (hgRepository) { + if (!nodePath) { + throw new Error('Invariant violation: "nodePath"'); + } + + (0, (_nuclideAnalytics || _load_nuclideAnalytics()).track)('hg-repository-add', { nodePath }); + yield hgRepository.addAll([nodePath]); + }); + + return function (_x3) { + return _ref3.apply(this, arguments); + }; + })()); } -export function revertPath(nodePath: ?NuclideUri, toRevision?: ?string): Promise { - return hgActionToPath( - nodePath, - 'revert', - 'Reverted', - async (hgRepository: HgRepositoryClient) => { - invariant(nodePath); - track('hg-repository-revert', {nodePath}); - await hgRepository.revert([nodePath], toRevision); - }, - ); +function revertPath(nodePath, toRevision) { + return hgActionToPath(nodePath, 'revert', 'Reverted', (() => { + var _ref4 = (0, _asyncToGenerator.default)(function* (hgRepository) { + if (!nodePath) { + throw new Error('Invariant violation: "nodePath"'); + } + + (0, (_nuclideAnalytics || _load_nuclideAnalytics()).track)('hg-repository-revert', { nodePath }); + yield hgRepository.revert([nodePath], toRevision); + }); + + return function (_x4) { + return _ref4.apply(this, arguments); + }; + })()); } -export function confirmAndRevertPath(path: ?NuclideUri, toRevision?: ?string): void { +function confirmAndRevertPath(path, toRevision) { const result = atom.confirm({ message: 'Are you sure you want to revert?', - buttons: ['Revert', 'Cancel'], + buttons: ['Revert', 'Cancel'] }); - invariant(result === 0 || result === 1); - if (result === 0) { - revertPath(path, toRevision); - } -} -async function hgActionToPath( - nodePath: ?NuclideUri, - actionName: string, - actionDoneMessage: string, - action: (hgRepository: HgRepositoryClient) => Promise, -): Promise { - if (nodePath == null || nodePath.length === 0) { - atom.notifications.addError(`Cannot ${actionName} an empty path!`); - return; + if (!(result === 0 || result === 1)) { + throw new Error('Invariant violation: "result === 0 || result === 1"'); } - const repository = repositoryForPath(nodePath); - if (repository == null || repository.getType() !== 'hg') { - atom.notifications.addError(`Cannot ${actionName} a non-mercurial repository path`); - return; - } - const hgRepository: HgRepositoryClient = (repository: any); - try { - await action(hgRepository); - atom.notifications.addSuccess( - `${actionDoneMessage} \`${repository.relativize(nodePath)}\` successfully.`, - ); - } catch (error) { - atom.notifications.addError( - `Failed to ${actionName} \`${repository.relativize(nodePath)}\``, - {detail: error.message}, - ); + + if (result === 0) { + revertPath(path, toRevision); } } -export function getHgRepositories(): Set { - return new Set( - (arrayCompact(atom.project.getRepositories()) - // Flow doesn't understand that this filters to hg repositories only, so cast through `any` - .filter(repository => repository.getType() === 'hg'): Array), - ); +function getHgRepositories() { + return new Set((0, (_collection || _load_collection()).arrayCompact)(atom.project.getRepositories()) + // Flow doesn't understand that this filters to hg repositories only, so cast through `any` + .filter(repository => repository.getType() === 'hg')); } -export function getHgRepositoryStream(): Observable { - const currentRepositories = - observableFromSubscribeFunction(atom.project.onDidChangePaths.bind(atom.project)) - .startWith(null) - .map(() => getHgRepositories()); +function getHgRepositoryStream() { + const currentRepositories = (0, (_event || _load_event()).observableFromSubscribeFunction)(atom.project.onDidChangePaths.bind(atom.project)).startWith(null).map(() => getHgRepositories()); - return diffSets(currentRepositories).flatMap( - repoDiff => Observable.from(repoDiff.added), - ); + return (0, (_observable || _load_observable()).diffSets)(currentRepositories).flatMap(repoDiff => _rxjsBundlesRxMinJs.Observable.from(repoDiff.added)); } /** @@ -237,21 +312,19 @@ export function getHgRepositoryStream(): Observable { * a Repository it belongs to. * @return A Git or Hg repository the path belongs to, if any. */ -export function repositoryForPath(aPath: NuclideUri): ?atom$Repository { +function repositoryForPath(aPath) { // Calling atom.project.repositoryForDirectory gets the real path of the directory, // which requires a round-trip to the server for remote paths. // Instead, this function keeps filtering local. - const repositories = arrayCompact(atom.project.getRepositories()); - return repositories.find( - repo => { - try { - return repositoryContainsPath(repo, aPath); - } catch (e) { - // The repo type is not supported. - return false; - } - }, - ); + const repositories = (0, (_collection || _load_collection()).arrayCompact)(atom.project.getRepositories()); + return repositories.find(repo => { + try { + return repositoryContainsPath(repo, aPath); + } catch (e) { + // The repo type is not supported. + return false; + } + }); } /** @@ -260,24 +333,20 @@ export function repositoryForPath(aPath: NuclideUri): ?atom$Repository { * @return boolean Whether the file path exists within the working directory * (aka root directory) of the repository, or is the working directory. */ -export function repositoryContainsPath( - repository: atom$Repository, - filePath: NuclideUri, -): boolean { +function repositoryContainsPath(repository, filePath) { const workingDirectoryPath = repository.getWorkingDirectory(); if (pathsAreEqual(workingDirectoryPath, filePath)) { return true; } if (repository.getType() === 'git') { - const rootGitProjectDirectory = new Directory(workingDirectoryPath); + const rootGitProjectDirectory = new _atom.Directory(workingDirectoryPath); return rootGitProjectDirectory.contains(filePath); } else if (repository.getType() === 'hg') { - const hgRepository = ((repository: any): HgRepositoryClient); + const hgRepository = repository; return hgRepository._workingDirectory.contains(filePath); } - throw new Error( - 'repositoryContainsPath: Received an unrecognized repository type. Expected git or hg.'); + throw new Error('repositoryContainsPath: Received an unrecognized repository type. Expected git or hg.'); } /** @@ -285,91 +354,61 @@ export function repositoryContainsPath( * @param filePath2 An absolute file path. * @return Whether the file paths are equal, accounting for trailing slashes. */ -function pathsAreEqual(filePath1: string, filePath2: string): boolean { - const realPath1 = nuclideUri.resolve(filePath1); - const realPath2 = nuclideUri.resolve(filePath2); +function pathsAreEqual(filePath1, filePath2) { + const realPath1 = (_nuclideUri || _load_nuclideUri()).default.resolve(filePath1); + const realPath2 = (_nuclideUri || _load_nuclideUri()).default.resolve(filePath2); return realPath1 === realPath2; } -export function filterMultiRootFileChanges( - unfilteredFileChanges: Map>, -): Map> { +function filterMultiRootFileChanges(unfilteredFileChanges) { const filteredFileChanges = new Map(); // Filtering the changes to make sure they only show up under the directory the // file exists under. for (const [root, fileChanges] of unfilteredFileChanges) { - const filteredFiles = mapFilter( - fileChanges, - filePath => filePath.startsWith(root), - ); + const filteredFiles = (0, (_collection || _load_collection()).mapFilter)(fileChanges, filePath => filePath.startsWith(root)); filteredFileChanges.set(root, filteredFiles); } return filteredFileChanges; } -export function getMultiRootFileChanges( - fileChanges: Map, - rootPaths?: Array, -): Map> { +function getMultiRootFileChanges(fileChanges, rootPaths) { let roots; if (rootPaths == null) { - roots = arrayCompact( - atom.project.getDirectories().map(directory => { - const rootPath = directory.getPath(); - const repository = repositoryForPath(rootPath); - if ((repository == null || repository.getType() !== 'hg')) { - return null; - } - return nuclideUri.ensureTrailingSeparator(rootPath); - }), - ); + roots = (0, (_collection || _load_collection()).arrayCompact)(atom.project.getDirectories().map(directory => { + const rootPath = directory.getPath(); + const repository = repositoryForPath(rootPath); + if (repository == null || repository.getType() !== 'hg') { + return null; + } + return (_nuclideUri || _load_nuclideUri()).default.ensureTrailingSeparator(rootPath); + })); } else { - roots = rootPaths.map(root => nuclideUri.ensureTrailingSeparator(root)); + roots = rootPaths.map(root => (_nuclideUri || _load_nuclideUri()).default.ensureTrailingSeparator(root)); } - const sortedFilePaths = Array.from(fileChanges.entries()) - .sort(([filePath1], [filePath2]) => - nuclideUri.basename(filePath1).toLowerCase().localeCompare( - nuclideUri.basename(filePath2).toLowerCase(), - ), - ); + const sortedFilePaths = Array.from(fileChanges.entries()).sort(([filePath1], [filePath2]) => (_nuclideUri || _load_nuclideUri()).default.basename(filePath1).toLowerCase().localeCompare((_nuclideUri || _load_nuclideUri()).default.basename(filePath2).toLowerCase())); const changedRoots = new Map(roots.map(root => { - const rootChanges = new Map( - sortedFilePaths.filter(([filePath]) => nuclideUri.contains(root, filePath)), - ); + const rootChanges = new Map(sortedFilePaths.filter(([filePath]) => (_nuclideUri || _load_nuclideUri()).default.contains(root, filePath))); return [root, rootChanges]; })); return changedRoots; } -export function confirmAndDeletePath(nuclideFilePath: NuclideUri): void { +function confirmAndDeletePath(nuclideFilePath) { const result = atom.confirm({ message: 'Are you sure you want to delete the following item?', - detailedMessage: `You are deleting: \n ${nuclideUri.getPath(nuclideFilePath)}`, - buttons: ['Delete', 'Cancel'], + detailedMessage: `You are deleting: \n ${(_nuclideUri || _load_nuclideUri()).default.getPath(nuclideFilePath)}`, + buttons: ['Delete', 'Cancel'] }); - invariant(result === 0 || result === 1); - if (result === 0) { - deleteFile(nuclideFilePath); + + if (!(result === 0 || result === 1)) { + throw new Error('Invariant violation: "result === 0 || result === 1"'); } -} -async function deleteFile(nuclideFilePath: string): Promise { - const filePath = nuclideUri.getPath(nuclideFilePath); - const fsService = getFileSystemServiceByNuclideUri(nuclideFilePath); - try { - await fsService.unlink(filePath); - const repository = repositoryForPath(nuclideFilePath); - if (repository == null || repository.getType() !== 'hg') { - return; - } - await ((repository: any): HgRepositoryClient).remove([filePath], true); - } catch (error) { - atom.notifications.addError('Failed to delete file', { - detail: error, - }); + if (result === 0) { + deleteFile(nuclideFilePath); } -} +} \ No newline at end of file diff --git a/pkg/commons-atom/viewableFromReactElement.js b/pkg/commons-atom/viewableFromReactElement.js index aa3f22e53f..ba90506b38 100644 --- a/pkg/commons-atom/viewableFromReactElement.js +++ b/pkg/commons-atom/viewableFromReactElement.js @@ -1,15 +1,19 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the license found in the LICENSE file in - * the root directory of this source tree. - * - * @flow - */ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.viewableFromReactElement = viewableFromReactElement; -import {React, ReactDOM} from 'react-for-atom'; -import ReactMountRootElement from '../nuclide-ui/ReactMountRootElement'; +var _reactForAtom = require('react-for-atom'); + +var _ReactMountRootElement; + +function _load_ReactMountRootElement() { + return _ReactMountRootElement = _interopRequireDefault(require('../nuclide-ui/ReactMountRootElement')); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /** * Create an object that can be used as an Atom model from a React element. Example: @@ -31,29 +35,35 @@ import ReactMountRootElement from '../nuclide-ui/ReactMountRootElement'; * const item = viewableFromReactElement(); * atom.workspace.getPanes()[0].addItem(item); // Or anywhere else Atom uses model "items." */ -export function viewableFromReactElement(reactElement: React.Element): Object { - const container = new ReactMountRootElement(); - const item = ReactDOM.render(reactElement, container); +/** + * Copyright (c) 2015-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the license found in the LICENSE file in + * the root directory of this source tree. + * + * + */ + +function viewableFromReactElement(reactElement) { + const container = new (_ReactMountRootElement || _load_ReactMountRootElement()).default(); + const item = _reactForAtom.ReactDOM.render(reactElement, container); // Add the a reference to the container to the item. This will allow Atom's view registry to // associate the item with the HTML element. if (item.element != null) { - throw new Error( - "Component cannot have an `element` property. That's added by viewableFromReactElement", - ); + throw new Error("Component cannot have an `element` property. That's added by viewableFromReactElement"); } - (item: any).element = container; + item.element = container; // Add a destroy method to the item that will unmount the component. There's no need for users to // implement this themselves because they have `componentWillUnmount()`. if (item.destroy != null) { - throw new Error( - "Component cannot implement `destroy()`. That's added by `viewableFromReactElement`", - ); + throw new Error("Component cannot implement `destroy()`. That's added by `viewableFromReactElement`"); } - (item: any).destroy = () => { - ReactDOM.unmountComponentAtNode(container); + item.destroy = () => { + _reactForAtom.ReactDOM.unmountComponentAtNode(container); }; return item; -} +} \ No newline at end of file diff --git a/pkg/commons-node/BatchProcessedQueue.js b/pkg/commons-node/BatchProcessedQueue.js index a04acc1bbf..fe9bf8303f 100644 --- a/pkg/commons-node/BatchProcessedQueue.js +++ b/pkg/commons-node/BatchProcessedQueue.js @@ -1,31 +1,22 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the license found in the LICENSE file in - * the root directory of this source tree. - * - * @flow - */ - -export type BatchHandler = (batch: Array) => void; +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + // A Queue which will process elements at intervals, only if the // queue contains any elements. -export default class BatchProcessedQueue { - _batchPeriod: number; - _handler: BatchHandler; - _timeoutId: ?number; - _items: Array; +class BatchProcessedQueue { - constructor(batchPeriod: number, handler: BatchHandler) { + constructor(batchPeriod, handler) { this._batchPeriod = batchPeriod; this._handler = handler; this._timeoutId = null; this._items = []; } - add(item: T): void { + add(item) { this._items.push(item); if (this._timeoutId === null) { this._timeoutId = setTimeout(() => { @@ -41,10 +32,21 @@ export default class BatchProcessedQueue { this._handler(batch); } - dispose(): void { + dispose() { if (this._timeoutId !== null) { clearTimeout(this._timeoutId); this._handleBatch(); } } } +exports.default = BatchProcessedQueue; /** + * Copyright (c) 2015-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the license found in the LICENSE file in + * the root directory of this source tree. + * + * + */ + +module.exports = exports["default"]; \ No newline at end of file diff --git a/pkg/commons-node/ConfigCache.js b/pkg/commons-node/ConfigCache.js index 453d7cd1a5..83c7d72656 100644 --- a/pkg/commons-node/ConfigCache.js +++ b/pkg/commons-node/ConfigCache.js @@ -1,3 +1,24 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.ConfigCache = undefined; + +var _lruCache; + +function _load_lruCache() { + return _lruCache = _interopRequireDefault(require('lru-cache')); +} + +var _fsPromise; + +function _load_fsPromise() { + return _fsPromise = _interopRequireDefault(require('./fsPromise')); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,37 +26,29 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * */ -import type {NuclideUri} from './nuclideUri'; -import type {LRUCache} from 'lru-cache'; - -import LRU from 'lru-cache'; -import fsPromise from './fsPromise'; - -export class ConfigCache { - _configFileName: string; - _configCache: LRUCache>; +class ConfigCache { - constructor(configFileName: string) { + constructor(configFileName) { this._configFileName = configFileName; - this._configCache = LRU({ + this._configCache = (0, (_lruCache || _load_lruCache()).default)({ max: 200, // Want this to exceed the maximum expected number of open files + dirs. - maxAge: 1000 * 30, // 30 seconds - }); + maxAge: 1000 * 30 }); } - getConfigDir(path: NuclideUri): Promise { + getConfigDir(path) { if (!this._configCache.has(path)) { - const result = fsPromise.findNearestFile(this._configFileName, path); + const result = (_fsPromise || _load_fsPromise()).default.findNearestFile(this._configFileName, path); this._configCache.set(path, result); return result; } return this._configCache.get(path); } - dispose(): void { + dispose() { this._configCache.reset(); } } +exports.ConfigCache = ConfigCache; \ No newline at end of file diff --git a/pkg/commons-node/Dispatcher.js b/pkg/commons-node/Dispatcher.js index f19b13bf92..3c550da3ee 100644 --- a/pkg/commons-node/Dispatcher.js +++ b/pkg/commons-node/Dispatcher.js @@ -1,20 +1,9 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the license found in the LICENSE file in - * the root directory of this source tree. - * - * @flow - */ - -/** - * Originally from https://github.com/facebook/flux/blob/55480fb/src/Dispatcher.js - */ +'use strict'; -import invariant from 'assert'; +Object.defineProperty(exports, "__esModule", { + value: true +}); -export type DispatchToken = string; const _prefix = 'ID_'; @@ -105,13 +94,21 @@ const _prefix = 'ID_'; * registered callbacks in order: `CountryStore`, `CityStore`, then * `FlightPriceStore`. */ -export default class Dispatcher { - _callbacks: {[key: DispatchToken]: (payload: TPayload) => void}; - _isDispatching: boolean; - _isHandled: {[key: DispatchToken]: boolean}; - _isPending: {[key: DispatchToken]: boolean}; - _lastID: number; - _pendingPayload: TPayload; +/** + * Copyright (c) 2015-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the license found in the LICENSE file in + * the root directory of this source tree. + * + * + */ + +/** + * Originally from https://github.com/facebook/flux/blob/55480fb/src/Dispatcher.js + */ + +class Dispatcher { constructor() { this._callbacks = {}; @@ -125,11 +122,11 @@ export default class Dispatcher { * Registers a callback to be invoked with every dispatched payload. Returns * a token that can be used with `waitFor()`. */ - register(callback: (payload: TPayload) => void): DispatchToken { - invariant( - !this._isDispatching, - 'Dispatcher.register(...): Cannot register in the middle of a dispatch.', - ); + register(callback) { + if (!!this._isDispatching) { + throw new Error('Dispatcher.register(...): Cannot register in the middle of a dispatch.'); + } + const id = _prefix + this._lastID++; this._callbacks[id] = callback; return id; @@ -138,16 +135,15 @@ export default class Dispatcher { /** * Removes a callback based on its token. */ - unregister(id: DispatchToken): void { - invariant( - !this._isDispatching, - 'Dispatcher.unregister(...): Cannot unregister in the middle of a dispatch.', - ); - invariant( - this._callbacks[id], - 'Dispatcher.unregister(...): `%s` does not map to a registered callback.', - id, - ); + unregister(id) { + if (!!this._isDispatching) { + throw new Error('Dispatcher.unregister(...): Cannot unregister in the middle of a dispatch.'); + } + + if (!this._callbacks[id]) { + throw new Error('Dispatcher.unregister(...): `%s` does not map to a registered callback.'); + } + delete this._callbacks[id]; } @@ -156,27 +152,25 @@ export default class Dispatcher { * of the current callback. This method should only be used by a callback in * response to a dispatched payload. */ - waitFor(ids: Array): void { - invariant( - this._isDispatching, - 'Dispatcher.waitFor(...): Must be invoked while dispatching.', - ); + waitFor(ids) { + if (!this._isDispatching) { + throw new Error('Dispatcher.waitFor(...): Must be invoked while dispatching.'); + } + for (let ii = 0; ii < ids.length; ii++) { const id = ids[ii]; if (this._isPending[id]) { - invariant( - this._isHandled[id], - 'Dispatcher.waitFor(...): Circular dependency detected while ' + - 'waiting for `%s`.', - id, - ); + if (!this._isHandled[id]) { + throw new Error('Dispatcher.waitFor(...): Circular dependency detected while ' + 'waiting for `%s`.'); + } + continue; } - invariant( - this._callbacks[id], - 'Dispatcher.waitFor(...): `%s` does not map to a registered callback.', - id, - ); + + if (!this._callbacks[id]) { + throw new Error('Dispatcher.waitFor(...): `%s` does not map to a registered callback.'); + } + this._invokeCallback(id); } } @@ -184,11 +178,11 @@ export default class Dispatcher { /** * Dispatches a payload to all registered callbacks. */ - dispatch(payload: TPayload): void { - invariant( - !this._isDispatching, - 'Dispatch.dispatch(...): Cannot dispatch in the middle of a dispatch.', - ); + dispatch(payload) { + if (!!this._isDispatching) { + throw new Error('Dispatch.dispatch(...): Cannot dispatch in the middle of a dispatch.'); + } + this._startDispatching(payload); try { for (const id in this._callbacks) { @@ -205,7 +199,7 @@ export default class Dispatcher { /** * Is this Dispatcher currently dispatching. */ - isDispatching(): boolean { + isDispatching() { return this._isDispatching; } @@ -215,7 +209,7 @@ export default class Dispatcher { * * @internal */ - _invokeCallback(id: DispatchToken): void { + _invokeCallback(id) { this._isPending[id] = true; this._callbacks[id](this._pendingPayload); this._isHandled[id] = true; @@ -226,7 +220,7 @@ export default class Dispatcher { * * @internal */ - _startDispatching(payload: TPayload): void { + _startDispatching(payload) { for (const id in this._callbacks) { this._isPending[id] = false; this._isHandled[id] = false; @@ -240,8 +234,10 @@ export default class Dispatcher { * * @internal */ - _stopDispatching(): void { + _stopDispatching() { delete this._pendingPayload; this._isDispatching = false; } } +exports.default = Dispatcher; +module.exports = exports['default']; \ No newline at end of file diff --git a/pkg/commons-node/Hasher.js b/pkg/commons-node/Hasher.js index ae65dd3929..f4ac0861d6 100644 --- a/pkg/commons-node/Hasher.js +++ b/pkg/commons-node/Hasher.js @@ -1,3 +1,8 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,7 +10,7 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * */ /** @@ -27,32 +32,29 @@ * } * } */ -export default class Hasher { - _hashes: WeakMap; - _objectCount: number; +class Hasher { constructor() { this._hashes = new WeakMap(); this._objectCount = 0; } - getHash(item: K): string | number { + getHash(item) { if (item === null) { return 'null'; } const type = typeof item; switch (typeof item) { - case 'object': { - let hash = this._hashes.get(item); - if (hash == null) { - hash = `${type}:${this._objectCount}`; - this._hashes.set(item, hash); - this._objectCount = this._objectCount + 1 === Number.MAX_SAFE_INTEGER - ? Number.MIN_SAFE_INTEGER - : this._objectCount + 1; + case 'object': + { + let hash = this._hashes.get(item); + if (hash == null) { + hash = `${type}:${this._objectCount}`; + this._hashes.set(item, hash); + this._objectCount = this._objectCount + 1 === Number.MAX_SAFE_INTEGER ? Number.MIN_SAFE_INTEGER : this._objectCount + 1; + } + return hash; } - return hash; - } case 'undefined': return 'undefined'; case 'string': @@ -65,3 +67,5 @@ export default class Hasher { } } } +exports.default = Hasher; +module.exports = exports['default']; \ No newline at end of file diff --git a/pkg/commons-node/ScribeProcess.js b/pkg/commons-node/ScribeProcess.js index a59c87ea0c..3c3827b6e6 100644 --- a/pkg/commons-node/ScribeProcess.js +++ b/pkg/commons-node/ScribeProcess.js @@ -1,3 +1,22 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.__test__ = undefined; + +var _asyncToGenerator = _interopRequireDefault(require('async-to-generator')); + +var _os = _interopRequireDefault(require('os')); + +var _process; + +function _load_process() { + return _process = require('./process'); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,12 +24,9 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * */ -import os from 'os'; -import {asyncExecute, safeSpawn} from './process'; - const DEFAULT_JOIN_TIMEOUT = 5000; let SCRIBE_CAT_COMMAND = 'scribe_cat'; @@ -20,12 +36,9 @@ let SCRIBE_CAT_COMMAND = 'scribe_cat'; * call `scribeProcess.write($object)` to save an JSON schemaed Object into scribe category. * It will also recover from `scribe_cat` failure automatically. */ -export default class ScribeProcess { - _scribeCategory: string; - _childProcess: ?child_process$ChildProcess; - _childProcessRunning: WeakMap; +class ScribeProcess { - constructor(scribeCategory: string) { + constructor(scribeCategory) { this._scribeCategory = scribeCategory; this._childProcessRunning = new WeakMap(); this._getOrCreateChildProcess(); @@ -34,23 +47,25 @@ export default class ScribeProcess { /** * Check if `scribe_cat` exists in PATH. */ - static async isScribeCatOnPath(): Promise { - const {exitCode} = await asyncExecute('which', [SCRIBE_CAT_COMMAND]); - return exitCode === 0; + static isScribeCatOnPath() { + return (0, _asyncToGenerator.default)(function* () { + const { exitCode } = yield (0, (_process || _load_process()).asyncExecute)('which', [SCRIBE_CAT_COMMAND]); + return exitCode === 0; + })(); } /** * Write a string to a Scribe category. * Ensure newlines are properly escaped. */ - write(message: string): Promise { + write(message) { const child = this._getOrCreateChildProcess(); return new Promise((resolve, reject) => { - child.stdin.write(`${message}${os.EOL}`, resolve); + child.stdin.write(`${message}${_os.default.EOL}`, resolve); }); } - dispose(): Promise { + dispose() { if (this._childProcess != null) { const child = this._childProcess; if (this._childProcessRunning.get(child)) { @@ -60,11 +75,11 @@ export default class ScribeProcess { return Promise.resolve(); } - join(timeout: number = DEFAULT_JOIN_TIMEOUT): Promise { + join(timeout = DEFAULT_JOIN_TIMEOUT) { if (this._childProcess != null) { - const {stdin} = this._childProcess; + const { stdin } = this._childProcess; // Make sure stdin has drained before ending it. - if (!stdin.write(os.EOL)) { + if (!stdin.write(_os.default.EOL)) { stdin.once('drain', () => stdin.end()); } else { stdin.end(); @@ -82,12 +97,12 @@ export default class ScribeProcess { } } - _getOrCreateChildProcess(): child_process$ChildProcess { + _getOrCreateChildProcess() { if (this._childProcess) { return this._childProcess; } - const child = this._childProcess = safeSpawn(SCRIBE_CAT_COMMAND, [this._scribeCategory]); + const child = this._childProcess = (0, (_process || _load_process()).safeSpawn)(SCRIBE_CAT_COMMAND, [this._scribeCategory]); child.stdin.setDefaultEncoding('utf8'); this._childProcessRunning.set(child, true); child.on('error', error => { @@ -103,10 +118,11 @@ export default class ScribeProcess { } } -export const __test__ = { - setScribeCatCommand(newCommand: string): string { +exports.default = ScribeProcess; +const __test__ = exports.__test__ = { + setScribeCatCommand(newCommand) { const originalCommand = SCRIBE_CAT_COMMAND; SCRIBE_CAT_COMMAND = newCommand; return originalCommand; - }, -}; + } +}; \ No newline at end of file diff --git a/pkg/commons-node/SharedObservableCache.js b/pkg/commons-node/SharedObservableCache.js index 94b4d773ac..009191dd54 100644 --- a/pkg/commons-node/SharedObservableCache.js +++ b/pkg/commons-node/SharedObservableCache.js @@ -1,14 +1,10 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the license found in the LICENSE file in - * the root directory of this source tree. - * - * @flow - */ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); -import {Observable} from 'rxjs'; +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js'); /** * This class creates and caches observables by key. @@ -18,25 +14,20 @@ import {Observable} from 'rxjs'; * * Once all subscribers to a key have unsubscribed, the cached observable is cleared. */ -export default class SharedObservableCache { - _factory: (key: Tk) => Observable; - _cache: Map, - }>; +class SharedObservableCache { - constructor(factory: (key: Tk) => Observable) { + constructor(factory) { this._factory = factory; this._cache = new Map(); } - get(key: Tk): Observable { - return Observable.create(observer => { + get(key) { + return _rxjsBundlesRxMinJs.Observable.create(observer => { let cached = this._cache.get(key); if (cached == null) { cached = { refCount: 1, - observable: this._factory(key), + observable: this._factory(key) }; } else { cached.refCount++; @@ -54,3 +45,14 @@ export default class SharedObservableCache { }); } } +exports.default = SharedObservableCache; /** + * Copyright (c) 2015-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the license found in the LICENSE file in + * the root directory of this source tree. + * + * + */ + +module.exports = exports['default']; \ No newline at end of file diff --git a/pkg/commons-node/SimpleModel.js b/pkg/commons-node/SimpleModel.js index e3d91e05a4..e59bd9219b 100644 --- a/pkg/commons-node/SimpleModel.js +++ b/pkg/commons-node/SimpleModel.js @@ -1,3 +1,24 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.SimpleModel = undefined; + +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js'); + +var _symbolObservable; + +function _load_symbolObservable() { + return _symbolObservable = _interopRequireDefault(require('symbol-observable')); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/** + * Exposes a simple, React-like OO API for a stateful model. Implements `Symbol.observable` so you + * can easily convert to an observable stream. + */ /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,35 +26,26 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * */ -import {Observable, Subject} from 'rxjs'; -import $$observable from 'symbol-observable'; - -/** - * Exposes a simple, React-like OO API for a stateful model. Implements `Symbol.observable` so you - * can easily convert to an observable stream. - */ -export class SimpleModel { - state: State; - _states: Subject; +class SimpleModel { constructor() { - this._states = new Subject(); - this._states.subscribe(state => { this.state = state; }); + this._states = new _rxjsBundlesRxMinJs.Subject(); + this._states.subscribe(state => { + this.state = state; + }); // Create an observable that contains the current, and all future, states. Since the initial // state is set directly (assigned to `this.state`), we can't just use a ReplaySubject // TODO: Use a computed property key when that's supported. - (this: any)[$$observable] = () => Observable.of(this.state).concat(this._states); + this[(_symbolObservable || _load_symbolObservable()).default] = () => _rxjsBundlesRxMinJs.Observable.of(this.state).concat(this._states); } - setState(newState: Object): void { - const nextState = { - ...this.state, - ...newState, - }; + setState(newState) { + const nextState = Object.assign({}, this.state, newState); this._states.next(nextState); } } +exports.SimpleModel = SimpleModel; \ No newline at end of file diff --git a/pkg/commons-node/UniversalDisposable.js b/pkg/commons-node/UniversalDisposable.js index 532d5c7fc4..c21e6aabc5 100644 --- a/pkg/commons-node/UniversalDisposable.js +++ b/pkg/commons-node/UniversalDisposable.js @@ -1,29 +1,22 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the license found in the LICENSE file in - * the root directory of this source tree. - * - * @flow - */ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); -type AnyTeardown = (() => mixed) | rxjs$ISubscription | IDisposable; /** * Like a CompositeDisposable, but in addition to Disposable instances it can * also accept plain functions and Rx subscriptions. */ -export default class UniversalDisposable { - _tearDowns: Set; - wasDisposed: boolean; +class UniversalDisposable { - constructor(...tearDowns: Array) { + constructor(...tearDowns) { this._tearDowns = new Set(tearDowns); this.wasDisposed = false; } - add(...tearDowns: Array): void { + add(...tearDowns) { if (this.wasDisposed) { throw new Error('Cannot add to an already disposed UniversalDisposable!'); } @@ -31,7 +24,7 @@ export default class UniversalDisposable { tearDowns.forEach(td => this._tearDowns.add(td)); } - remove(...tearDowns: Array): void { + remove(...tearDowns) { if (this.wasDisposed) { return; } @@ -39,7 +32,7 @@ export default class UniversalDisposable { tearDowns.forEach(td => this._tearDowns.delete(td)); } - dispose(): void { + dispose() { if (this.wasDisposed) { return; } @@ -57,11 +50,11 @@ export default class UniversalDisposable { this.wasDisposed = true; } - unsubscribe(): void { + unsubscribe() { this.dispose(); } - clear(): void { + clear() { if (this.wasDisposed) { return; } @@ -69,3 +62,14 @@ export default class UniversalDisposable { this._tearDowns.clear(); } } +exports.default = UniversalDisposable; /** + * Copyright (c) 2015-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the license found in the LICENSE file in + * the root directory of this source tree. + * + * + */ + +module.exports = exports['default']; \ No newline at end of file diff --git a/pkg/commons-node/cache.js b/pkg/commons-node/cache.js index 49201c9e81..91718c2ff5 100644 --- a/pkg/commons-node/cache.js +++ b/pkg/commons-node/cache.js @@ -1,37 +1,27 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the license found in the LICENSE file in - * the root directory of this source tree. - * - * @flow - */ +'use strict'; -import {Observable, Subject} from 'rxjs'; +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.DISPOSE_VALUE = exports.Cache = undefined; + +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js'); // A Cache mapping keys to values which creates entries as they are requested. -export class Cache { - _values: Map; - _factory: (key: KeyType) => ValueType; - _disposeValue: (value: ValueType) => mixed; - _entriesSubject: Subject<[KeyType, ValueType]>; - - constructor( - factory: (key: KeyType) => ValueType, - disposeValue: (value: ValueType) => mixed = value => {}, - ) { +class Cache { + + constructor(factory, disposeValue = value => {}) { this._values = new Map(); this._factory = factory; this._disposeValue = disposeValue; - this._entriesSubject = new Subject(); + this._entriesSubject = new _rxjsBundlesRxMinJs.Subject(); } - has(key: KeyType): boolean { + has(key) { return this._values.has(key); } - get(key: KeyType): ValueType { + get(key) { if (!this._values.has(key)) { const newValue = this._factory(key); this._values.set(key, newValue); @@ -39,14 +29,14 @@ export class Cache { return newValue; } else { // Cannot use invariant as ValueType may include null/undefined. - return (this._values.get(key): any); + return this._values.get(key); } } // After this method this._values.keys() === newKeys. // deletes all keys not in newKeys // gets all keys in newKeys - setKeys(newKeys: Set): void { + setKeys(newKeys) { for (const existingKey of this._values.keys()) { if (!newKeys.has(existingKey)) { this.delete(existingKey); @@ -58,29 +48,27 @@ export class Cache { } } - keys(): Iterator { + keys() { return this._values.keys(); } - values(): Iterator { + values() { return this._values.values(); } - observeValues(): Observable { + observeValues() { return this.observeEntries().map(entry => entry[1]); } - observeEntries(): Observable<[KeyType, ValueType]> { - return Observable.concat( - Observable.from(this._values.entries()), - this._entriesSubject); + observeEntries() { + return _rxjsBundlesRxMinJs.Observable.concat(_rxjsBundlesRxMinJs.Observable.from(this._values.entries()), this._entriesSubject); } - observeKeys(): Observable { + observeKeys() { return this.observeEntries().map(entry => entry[0]); } - delete(key: KeyType): boolean { + delete(key) { if (this.has(key)) { const value = this.get(key); this._values.delete(key); @@ -91,7 +79,7 @@ export class Cache { } } - clear(): void { + clear() { // Defend against a dispose call removing elements from the Cache. const values = this._values; this._values = new Map(); @@ -100,11 +88,23 @@ export class Cache { } } - dispose(): void { + dispose() { this.clear(); this._entriesSubject.complete(); } } -// Useful for optional second parameter to Cache constructor. -export const DISPOSE_VALUE = (value: IDisposable) => { value.dispose(); }; +exports.Cache = Cache; // Useful for optional second parameter to Cache constructor. +/** + * Copyright (c) 2015-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the license found in the LICENSE file in + * the root directory of this source tree. + * + * + */ + +const DISPOSE_VALUE = exports.DISPOSE_VALUE = value => { + value.dispose(); +}; \ No newline at end of file diff --git a/pkg/commons-node/collection.js b/pkg/commons-node/collection.js index 94babd2981..cedf7752b1 100644 --- a/pkg/commons-node/collection.js +++ b/pkg/commons-node/collection.js @@ -1,3 +1,32 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.arrayRemove = arrayRemove; +exports.arrayEqual = arrayEqual; +exports.arrayCompact = arrayCompact; +exports.arrayFindLastIndex = arrayFindLastIndex; +exports.mapUnion = mapUnion; +exports.mapFilter = mapFilter; +exports.mapEqual = mapEqual; +exports.areSetsEqual = areSetsEqual; +exports.every = every; +exports.setIntersect = setIntersect; +exports.setDifference = setDifference; +exports.isEmpty = isEmpty; +exports.keyMirror = keyMirror; +exports.collect = collect; +exports.objectEntries = objectEntries; +exports.objectFromMap = objectFromMap; +exports.concatIterators = concatIterators; +exports.someOfIterable = someOfIterable; +exports.findInIterable = findInIterable; +exports.filterIterable = filterIterable; +exports.mapIterable = mapIterable; +exports.firstOfIterable = firstOfIterable; +exports.iterableIsEmpty = iterableIsEmpty; +exports.iterableContains = iterableContains; /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,25 +34,21 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * */ -export function arrayRemove(array: Array, element: T): void { +function arrayRemove(array, element) { const index = array.indexOf(element); if (index >= 0) { array.splice(index, 1); } } -export function arrayEqual( - array1: Array, - array2: Array, - equalComparator?: (a: T, b: T) => boolean, -): boolean { +function arrayEqual(array1, array2, equalComparator) { if (array1.length !== array2.length) { return false; } - const equalFunction = equalComparator || ((a: T, b: T) => a === b); + const equalFunction = equalComparator || ((a, b) => a === b); return array1.every((item1, i) => equalFunction(item1, array2[i])); } @@ -31,7 +56,7 @@ export function arrayEqual( * Returns a copy of the input Array with all `null` and `undefined` values filtered out. * Allows Flow to typecheck the common `filter(x => x != null)` pattern. */ -export function arrayCompact(array: Array): Array { +function arrayCompact(array) { const result = []; for (const elem of array) { if (elem != null) { @@ -45,11 +70,7 @@ export function arrayCompact(array: Array): Array { * Returns the last index in the input array that matches the predicate. * Returns -1 if no match is found. */ -export function arrayFindLastIndex( - array: Array, - predicate: (elem: T, index: number, array: Array) => boolean, - thisArg?: any, -): number { +function arrayFindLastIndex(array, predicate, thisArg) { for (let i = array.length - 1; i >= 0; i--) { if (predicate.call(thisArg, array[i], i, array)) { return i; @@ -62,7 +83,7 @@ export function arrayFindLastIndex( * Merges a given arguments of maps into one Map, with the latest maps * overriding the values of the prior maps. */ -export function mapUnion(...maps: Array>): Map { +function mapUnion(...maps) { const unionMap = new Map(); for (const map of maps) { for (const [key, value] of map) { @@ -72,10 +93,7 @@ export function mapUnion(...maps: Array>): Map { return unionMap; } -export function mapFilter( - map: Map, - selector: (key: T, value: X) => boolean, -): Map { +function mapFilter(map, selector) { const selected = new Map(); for (const [key, value] of map) { if (selector(key, value)) { @@ -85,29 +103,25 @@ export function mapFilter( return selected; } -export function mapEqual( - map1: Map, - map2: Map, - equalComparator?: (val1: X, val2: X, key1?: T, key2?: T) => boolean, -) { +function mapEqual(map1, map2, equalComparator) { if (map1.size !== map2.size) { return false; } - const equalFunction = equalComparator || ((a: X, b: X) => a === b); + const equalFunction = equalComparator || ((a, b) => a === b); for (const [key1, value1] of map1) { - if (!map2.has(key1) || !equalFunction(value1, (map2.get(key1): any))) { + if (!map2.has(key1) || !equalFunction(value1, map2.get(key1))) { return false; } } return true; } -export function areSetsEqual(a: Set, b: Set): boolean { +function areSetsEqual(a, b) { return a.size === b.size && every(a, element => b.has(element)); } // Array.every but for any iterable. -export function every(values: Iterable, predicate: (element: T) => boolean): boolean { +function every(values, predicate) { for (const element of values) { if (!predicate(element)) { return false; @@ -116,11 +130,11 @@ export function every(values: Iterable, predicate: (element: T) => boolean return true; } -export function setIntersect(a: Set, b: Set): Set { +function setIntersect(a, b) { return new Set(Array.from(a).filter(e => b.has(e))); } -export function setDifference(a: Set, b: Set, hash_?: (v: T) => any): Set { +function setDifference(a, b, hash_) { if (a.size === 0) { return new Set(); } else if (b.size === 0) { @@ -140,7 +154,7 @@ export function setDifference(a: Set, b: Set, hash_?: (v: T) => any): S /** * O(1)-check if a given object is empty (has no properties, inherited or not) */ -export function isEmpty(obj: Object): boolean { +function isEmpty(obj) { for (const key in obj) { return false; } @@ -153,7 +167,7 @@ export function isEmpty(obj: Object): boolean { * * Based off the equivalent function in www. */ -export function keyMirror(obj: T): {[key: $Enum]: $Enum} { +function keyMirror(obj) { const ret = {}; Object.keys(obj).forEach(key => { ret[key] = key; @@ -165,7 +179,7 @@ export function keyMirror(obj: T): {[key: $Enum]: $Enum} { * Given an array of [key, value] pairs, construct a map where the values for * each key are collected into an array of values, in order. */ -export function collect(pairs: Array<[K, V]>): Map> { +function collect(pairs) { const result = new Map(); for (const pair of pairs) { const [k, v] = pair; @@ -179,17 +193,8 @@ export function collect(pairs: Array<[K, V]>): Map> { return result; } -export class MultiMap { +class MultiMap { // Invariant: no empty sets. They should be removed instead. - _map: Map>; - - // TODO may be worth defining a getter but no setter, to mimic Map. But please just behave and - // don't mutate this from outside this class. - // - // Invariant: equal to the sum of the sizes of all the sets contained in this._map - /* The total number of key-value bindings contained */ - size: number; - constructor() { this._map = new Map(); this.size = 0; @@ -199,7 +204,14 @@ export class MultiMap { * Returns the set of values associated with the given key. Do not mutate the given set. Copy it * if you need to store it past the next operation on this MultiMap. */ - get(key: K): Set { + + + // TODO may be worth defining a getter but no setter, to mimic Map. But please just behave and + // don't mutate this from outside this class. + // + // Invariant: equal to the sum of the sizes of all the sets contained in this._map + /* The total number of key-value bindings contained */ + get(key) { const set = this._map.get(key); if (set == null) { return new Set(); @@ -211,7 +223,7 @@ export class MultiMap { * Mimics the Map.prototype.set interface. Deliberately did not choose "set" as the name since the * implication is that it removes the previous binding. */ - add(key: K, value: V): MultiMap { + add(key, value) { let set = this._map.get(key); if (set == null) { set = new Set(); @@ -227,7 +239,7 @@ export class MultiMap { /* * Mimics the Map.prototype.set interface. Replaces the previous binding with new values. */ - set(key: K, values: Iterable): void { + set(key, values) { this.deleteAll(key); const newSet = new Set(values); if (newSet.size !== 0) { @@ -239,7 +251,7 @@ export class MultiMap { /* * Deletes a single binding. Returns true iff the binding existed. */ - delete(key: K, value: V): boolean { + delete(key, value) { const set = this.get(key); const didRemove = set.delete(value); if (set.size === 0) { @@ -254,38 +266,41 @@ export class MultiMap { /* * Deletes all bindings associated with the given key. Returns true iff any bindings were deleted. */ - deleteAll(key: K): boolean { + deleteAll(key) { const set = this.get(key); this.size -= set.size; return this._map.delete(key); } - clear(): void { + clear() { this._map.clear(); this.size = 0; } - has(key: K, value: V): boolean { + has(key, value) { return this.get(key).has(value); } - hasAny(key: K): boolean { + hasAny(key) { return this._map.has(key); } - *values(): Iterable { + *values() { for (const set of this._map.values()) { yield* set; } } - forEach(callback: (value: V, key: K, obj: MultiMap) => void): void { + forEach(callback) { this._map.forEach((values, key) => values.forEach(value => callback(value, key, this))); } } -export function objectEntries(obj: {[key: string]: T}): Array<[string, T]> { - if (obj == null) { throw new TypeError(); } +exports.MultiMap = MultiMap; +function objectEntries(obj) { + if (obj == null) { + throw new TypeError(); + } const entries = []; for (const key in obj) { if (obj.hasOwnProperty(key) && Object.prototype.propertyIsEnumerable.call(obj, key)) { @@ -295,13 +310,15 @@ export function objectEntries(obj: {[key: string]: T}): Array<[string, T]> { return entries; } -export function objectFromMap(map: Map): {[key: string]: T} { +function objectFromMap(map) { const obj = {}; - map.forEach((v, k) => { obj[k] = v; }); + map.forEach((v, k) => { + obj[k] = v; + }); return obj; } -export function *concatIterators(...iterators: Array>): Iterator { +function* concatIterators(...iterators) { for (const iterator of iterators) { for (const element of iterator) { yield element; @@ -309,10 +326,7 @@ export function *concatIterators(...iterators: Array>): Iterator< } } -export function someOfIterable( - iterable: Iterable, - predicate: (element: T) => boolean, -): boolean { +function someOfIterable(iterable, predicate) { for (const element of iterable) { if (predicate(element)) { return true; @@ -321,10 +335,7 @@ export function someOfIterable( return false; } -export function findInIterable( - iterable: Iterable, - predicate: (element: T) => boolean, -): ?T { +function findInIterable(iterable, predicate) { for (const element of iterable) { if (predicate(element)) { return element; @@ -333,10 +344,7 @@ export function findInIterable( return null; } -export function *filterIterable( - iterable: Iterable, - predicate: (element: T) => boolean, -): Iterable { +function* filterIterable(iterable, predicate) { for (const element of iterable) { if (predicate(element)) { yield element; @@ -344,20 +352,17 @@ export function *filterIterable( } } -export function *mapIterable( - iterable: Iterable, - projectorFn: (element: T) => M, -): Iterable { +function* mapIterable(iterable, projectorFn) { for (const element of iterable) { yield projectorFn(element); } } -export function firstOfIterable(iterable: Iterable): ?T { +function firstOfIterable(iterable) { return findInIterable(iterable, () => true); } -export function iterableIsEmpty(iterable: Iterable): boolean { +function iterableIsEmpty(iterable) { // eslint-disable-next-line no-unused-vars for (const element of iterable) { return false; @@ -365,6 +370,6 @@ export function iterableIsEmpty(iterable: Iterable): boolean { return true; } -export function iterableContains(iterable: Iterable, value: T): boolean { +function iterableContains(iterable, value) { return !iterableIsEmpty(filterIterable(iterable, element => element === value)); -} +} \ No newline at end of file diff --git a/pkg/commons-node/compareVersions.js b/pkg/commons-node/compareVersions.js index 929927db8f..57bf5bac95 100644 --- a/pkg/commons-node/compareVersions.js +++ b/pkg/commons-node/compareVersions.js @@ -1,3 +1,9 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = compareVersions; /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,21 +11,26 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * */ /** * Compare two version strings. This is much more lax than semver and allows, for example, versions * like "9". */ -export default function compareVersions(a: string, b: string): number { +function compareVersions(a, b) { const aParts = a.split('.').map(x => parseInt(x, 10)); const bParts = b.split('.').map(x => parseInt(x, 10)); for (let i = 0; i < Math.max(aParts.length, bParts.length); i++) { const aNumber = aParts[i] || 0; const bNumber = bParts[i] || 0; - if (aNumber < bNumber) { return -1; } - if (aNumber > bNumber) { return 1; } + if (aNumber < bNumber) { + return -1; + } + if (aNumber > bNumber) { + return 1; + } } return 0; } +module.exports = exports['default']; \ No newline at end of file diff --git a/pkg/commons-node/debounce.js b/pkg/commons-node/debounce.js index 4e26ab3f07..7f202dbd22 100644 --- a/pkg/commons-node/debounce.js +++ b/pkg/commons-node/debounce.js @@ -1,35 +1,18 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the license found in the LICENSE file in - * the root directory of this source tree. - * - * @flow - */ +'use strict'; -import invariant from 'assert'; - -export default function debounce< - A, B, C, D, E, F, G, - TReturn, - TFunc:(a: A, b: B, c: C, d: D, e: E, f: F, g: G) => TReturn, ->( - func: TFunc, - wait: number, - immediate?: boolean = false, -): { - (a: A, b: B, c: C, d: D, e: E, f: F, g: G): TReturn | void, - dispose(): void, -} { +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = debounce; +function debounce(func, wait, immediate = false) { // Taken from: https://github.com/jashkenas/underscore/blob/b10b2e6d72/underscore.js#L815. - let timeout: ?number; - let args: ?[A, B, C, D, E, F, G]; - let context: any; + let timeout; + let args; + let context; let timestamp = 0; - let result: (TReturn | void); + let result; - const later = function() { + const later = function () { const last = Date.now() - timestamp; if (last < wait && last >= 0) { @@ -37,7 +20,10 @@ export default function debounce< } else { timeout = null; if (!immediate) { - invariant(args != null); + if (!(args != null)) { + throw new Error('Invariant violation: "args != null"'); + } + result = func.apply(context, args); if (!timeout) { context = args = null; @@ -46,9 +32,9 @@ export default function debounce< } }; - const debounced = function(): (TReturn | void) { + const debounced = function () { context = this; - args = (arguments: [A, B, C, D, E, F, G]); + args = arguments; timestamp = Date.now(); const callNow = immediate && !timeout; if (!timeout) { @@ -70,4 +56,14 @@ export default function debounce< }; return debounced; -} +} /** + * Copyright (c) 2015-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the license found in the LICENSE file in + * the root directory of this source tree. + * + * + */ + +module.exports = exports['default']; \ No newline at end of file diff --git a/pkg/commons-node/event.js b/pkg/commons-node/event.js index e4dd01df26..71df0d6069 100644 --- a/pkg/commons-node/event.js +++ b/pkg/commons-node/event.js @@ -1,3 +1,24 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.attachEvent = attachEvent; +exports.observableFromSubscribeFunction = observableFromSubscribeFunction; + +var _eventKit; + +function _load_eventKit() { + return _eventKit = require('event-kit'); +} + +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js'); + +/** + * Add an event listener an return a disposable for removing it. Note that this function assumes + * node EventEmitter semantics: namely, that adding the same combination of eventName and callback + * adds a second listener. + */ /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,34 +26,21 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * */ -import {Disposable} from 'event-kit'; -import {Observable} from 'rxjs'; - -/** - * Add an event listener an return a disposable for removing it. Note that this function assumes - * node EventEmitter semantics: namely, that adding the same combination of eventName and callback - * adds a second listener. - */ -export function attachEvent( - emitter: events$EventEmitter, - eventName: string, - callback: Function, -): Disposable { +function attachEvent(emitter, eventName, callback) { emitter.addListener(eventName, callback); - return new Disposable(() => { + return new (_eventKit || _load_eventKit()).Disposable(() => { emitter.removeListener(eventName, callback); }); } -type SubscribeCallback = (item: T) => any; -type SubscribeFunction = (callback: SubscribeCallback) => IDisposable; - -export function observableFromSubscribeFunction(fn: SubscribeFunction): Observable { - return Observable.create(observer => { +function observableFromSubscribeFunction(fn) { + return _rxjsBundlesRxMinJs.Observable.create(observer => { const disposable = fn(observer.next.bind(observer)); - return () => { disposable.dispose(); }; + return () => { + disposable.dispose(); + }; }); -} +} \ No newline at end of file diff --git a/pkg/commons-node/fsPromise.js b/pkg/commons-node/fsPromise.js index 55f77ee48d..06d0483ecf 100644 --- a/pkg/commons-node/fsPromise.js +++ b/pkg/commons-node/fsPromise.js @@ -1,21 +1,205 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _asyncToGenerator = _interopRequireDefault(require('async-to-generator')); + /** - * Copyright (c) 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the license found in the LICENSE file in - * the root directory of this source tree. + * Searches upward through the filesystem from pathToDirectory to find a file with + * fileName. + * @param fileName The name of the file to find. + * @param pathToDirectory Where to begin the search. Must be a path to a directory, + * not a file. + * @return directory that contains the nearest file or null. + */ +let findNearestFile = (() => { + var _ref = (0, _asyncToGenerator.default)(function* (fileName, pathToDirectory) { + // TODO(5586355): If this becomes a bottleneck, we should consider memoizing + // this function. The downside would be that if someone added a closer file + // with fileName to pathToFile (or deleted the one that was cached), then we + // would have a bug. This would probably be pretty rare, though. + let currentPath = (_nuclideUri || _load_nuclideUri()).default.resolve(pathToDirectory); + for (;;) { + const fileToFind = (_nuclideUri || _load_nuclideUri()).default.join(currentPath, fileName); + // eslint-disable-next-line no-await-in-loop + const hasFile = yield exists(fileToFind); + if (hasFile) { + return currentPath; + } + if ((_nuclideUri || _load_nuclideUri()).default.isRoot(currentPath)) { + return null; + } + currentPath = (_nuclideUri || _load_nuclideUri()).default.dirname(currentPath); + } + }); + + return function findNearestFile(_x, _x2) { + return _ref.apply(this, arguments); + }; +})(); + +/** + * Searches upward through the filesystem from pathToDirectory to find the furthest + * file with fileName. + * @param fileName The name of the file to find. + * @param pathToDirectory Where to begin the search. Must be a path to a directory, + * not a file. + * @param stopOnMissing Stop searching when we reach a directory without fileName. + * @return directory that contains the furthest file or null. + */ + + +let findFurthestFile = (() => { + var _ref2 = (0, _asyncToGenerator.default)(function* (fileName, pathToDirectory, stopOnMissing = false) { + let currentPath = (_nuclideUri || _load_nuclideUri()).default.resolve(pathToDirectory); + let result = null; + for (;;) { + const fileToFind = (_nuclideUri || _load_nuclideUri()).default.join(currentPath, fileName); + // eslint-disable-next-line no-await-in-loop + const hasFile = yield exists(fileToFind); + if (!hasFile && stopOnMissing || (_nuclideUri || _load_nuclideUri()).default.isRoot(currentPath)) { + return result; + } else if (hasFile) { + result = currentPath; + } + currentPath = (_nuclideUri || _load_nuclideUri()).default.dirname(currentPath); + } + }); + + return function findFurthestFile(_x3, _x4) { + return _ref2.apply(this, arguments); + }; +})(); + +/** + * Runs the equivalent of `mkdir -p` with the given path. * - * @flow + * Like most implementations of mkdirp, if it fails, it is possible that + * directories were created for some prefix of the given path. + * @return true if the path was created; false if it already existed. */ +let mkdirp = (() => { + var _ref3 = (0, _asyncToGenerator.default)(function* (filePath) { + const isExistingDirectory = yield exists(filePath); + if (isExistingDirectory) { + return false; + } else { + return new Promise(function (resolve, reject) { + (0, (_mkdirp || _load_mkdirp()).default)(filePath, function (err) { + if (err) { + reject(err); + } else { + resolve(true); + } + }); + }); + } + }); + + return function mkdirp(_x5) { + return _ref3.apply(this, arguments); + }; +})(); + +/** + * Removes directories even if they are non-empty. Does not fail if the directory doesn't exist. + */ + + +/** @return true only if we are sure directoryPath is on NFS. */ +let isNfs = (() => { + var _ref4 = (0, _asyncToGenerator.default)(function* (entityPath) { + if (process.platform === 'linux' || process.platform === 'darwin') { + const { stdout, exitCode } = yield (0, (_process || _load_process()).asyncExecute)('stat', ['-f', '-L', '-c', '%T', entityPath]); + if (exitCode === 0) { + return stdout.trim() === 'nfs'; + } else { + return false; + } + } else { + // TODO Handle other platforms (windows?): t9917576. + return false; + } + }); -import fs from 'fs'; -import fsPlus from 'fs-plus'; -import globLib from 'glob'; -import mkdirpLib from 'mkdirp'; -import nuclideUri from '../commons-node/nuclideUri'; -import rimraf from 'rimraf'; -import temp from 'temp'; -import {asyncExecute} from './process'; + return function isNfs(_x6) { + return _ref4.apply(this, arguments); + }; +})(); + +let isNonNfsDirectory = (() => { + var _ref5 = (0, _asyncToGenerator.default)(function* (directoryPath) { + try { + const stats = yield stat(directoryPath); + if (stats.isDirectory()) { + return !(yield isNfs(directoryPath)); + } else { + return false; + } + } catch (e) { + // If the directory cannot be probed for whatever reason, just + // indicate that this is not a valid candidate directory. + // Typically this is ENOENT for missing directory. + return false; + } + }); + + return function isNonNfsDirectory(_x7) { + return _ref5.apply(this, arguments); + }; +})(); + +/** + * Promisified wrappers around fs-plus functions. + */ + +var _fs = _interopRequireDefault(require('fs')); + +var _fsPlus; + +function _load_fsPlus() { + return _fsPlus = _interopRequireDefault(require('fs-plus')); +} + +var _glob; + +function _load_glob() { + return _glob = _interopRequireDefault(require('glob')); +} + +var _mkdirp; + +function _load_mkdirp() { + return _mkdirp = _interopRequireDefault(require('mkdirp')); +} + +var _nuclideUri; + +function _load_nuclideUri() { + return _nuclideUri = _interopRequireDefault(require('../commons-node/nuclideUri')); +} + +var _rimraf; + +function _load_rimraf() { + return _rimraf = _interopRequireDefault(require('rimraf')); +} + +var _temp; + +function _load_temp() { + return _temp = _interopRequireDefault(require('temp')); +} + +var _process; + +function _load_process() { + return _process = require('./process'); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /** * Create a temp directory with given prefix. The caller is responsible for cleaning up the @@ -23,9 +207,19 @@ import {asyncExecute} from './process'; * @param prefix optinal prefix for the temp directory name. * @return path to a temporary directory. */ -function tempdir(prefix: string = ''): Promise { +/** + * Copyright (c) 2015-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the license found in the LICENSE file in + * the root directory of this source tree. + * + * + */ + +function tempdir(prefix = '') { return new Promise((resolve, reject) => { - temp.mkdir(prefix, (err, result) => { + (_temp || _load_temp()).default.mkdir(prefix, (err, result) => { if (err == null) { resolve(result); } else { @@ -39,13 +233,13 @@ function tempdir(prefix: string = ''): Promise { * @return path to a temporary file. The caller is responsible for cleaning up * the file. */ -function tempfile(options: any): Promise { +function tempfile(options) { return new Promise((resolve, reject) => { - temp.open(options, (err, info) => { + (_temp || _load_temp()).default.open(options, (err, info) => { if (err) { reject(err); } else { - fs.close(info.fd, closeErr => { + _fs.default.close(info.fd, closeErr => { if (closeErr) { reject(closeErr); } else { @@ -57,108 +251,21 @@ function tempfile(options: any): Promise { }); } -/** - * Searches upward through the filesystem from pathToDirectory to find a file with - * fileName. - * @param fileName The name of the file to find. - * @param pathToDirectory Where to begin the search. Must be a path to a directory, - * not a file. - * @return directory that contains the nearest file or null. - */ -async function findNearestFile(fileName: string, pathToDirectory: string): Promise { - // TODO(5586355): If this becomes a bottleneck, we should consider memoizing - // this function. The downside would be that if someone added a closer file - // with fileName to pathToFile (or deleted the one that was cached), then we - // would have a bug. This would probably be pretty rare, though. - let currentPath = nuclideUri.resolve(pathToDirectory); - for (;;) { - const fileToFind = nuclideUri.join(currentPath, fileName); - // eslint-disable-next-line no-await-in-loop - const hasFile = await exists(fileToFind); - if (hasFile) { - return currentPath; - } - if (nuclideUri.isRoot(currentPath)) { - return null; - } - currentPath = nuclideUri.dirname(currentPath); - } -} - -/** - * Searches upward through the filesystem from pathToDirectory to find the furthest - * file with fileName. - * @param fileName The name of the file to find. - * @param pathToDirectory Where to begin the search. Must be a path to a directory, - * not a file. - * @param stopOnMissing Stop searching when we reach a directory without fileName. - * @return directory that contains the furthest file or null. - */ -async function findFurthestFile( - fileName: string, - pathToDirectory: string, - stopOnMissing: boolean = false, -): Promise { - let currentPath = nuclideUri.resolve(pathToDirectory); - let result = null; - for (;;) { - const fileToFind = nuclideUri.join(currentPath, fileName); - // eslint-disable-next-line no-await-in-loop - const hasFile = await exists(fileToFind); - if ((!hasFile && stopOnMissing) || nuclideUri.isRoot(currentPath)) { - return result; - } else if (hasFile) { - result = currentPath; - } - currentPath = nuclideUri.dirname(currentPath); - } -} - -function getCommonAncestorDirectory(filePaths: Array): string { - let commonDirectoryPath = nuclideUri.dirname(filePaths[0]); +function getCommonAncestorDirectory(filePaths) { + let commonDirectoryPath = (_nuclideUri || _load_nuclideUri()).default.dirname(filePaths[0]); while (filePaths.some(filePath => !filePath.startsWith(commonDirectoryPath))) { - commonDirectoryPath = nuclideUri.dirname(commonDirectoryPath); + commonDirectoryPath = (_nuclideUri || _load_nuclideUri()).default.dirname(commonDirectoryPath); } return commonDirectoryPath; } - -function exists(filePath: string): Promise { +function exists(filePath) { return new Promise((resolve, reject) => { - fs.exists(filePath, resolve); + _fs.default.exists(filePath, resolve); }); -} - -/** - * Runs the equivalent of `mkdir -p` with the given path. - * - * Like most implementations of mkdirp, if it fails, it is possible that - * directories were created for some prefix of the given path. - * @return true if the path was created; false if it already existed. - */ -async function mkdirp(filePath: string): Promise { - const isExistingDirectory = await exists(filePath); - if (isExistingDirectory) { - return false; - } else { - return new Promise((resolve, reject) => { - mkdirpLib(filePath, err => { - if (err) { - reject(err); - } else { - resolve(true); - } - }); - }); - } -} - -/** - * Removes directories even if they are non-empty. Does not fail if the directory doesn't exist. - */ -function rmdir(filePath: string): Promise { +}function rmdir(filePath) { return new Promise((resolve, reject) => { - rimraf(filePath, (err, result) => { + (0, (_rimraf || _load_rimraf()).default)(filePath, (err, result) => { if (err == null) { resolve(result); } else { @@ -168,24 +275,9 @@ function rmdir(filePath: string): Promise { }); } -/** @return true only if we are sure directoryPath is on NFS. */ -async function isNfs(entityPath: string): Promise { - if (process.platform === 'linux' || process.platform === 'darwin') { - const {stdout, exitCode} = await asyncExecute('stat', ['-f', '-L', '-c', '%T', entityPath]); - if (exitCode === 0) { - return stdout.trim() === 'nfs'; - } else { - return false; - } - } else { - // TODO Handle other platforms (windows?): t9917576. - return false; - } -} - -function glob(pattern: string, options?: Object): Promise> { +function glob(pattern, options) { return new Promise((resolve, reject) => { - globLib(pattern, options, (err, result) => { + (0, (_glob || _load_glob()).default)(pattern, options, (err, result) => { if (err == null) { resolve(result); } else { @@ -195,29 +287,9 @@ function glob(pattern: string, options?: Object): Promise> { }); } -async function isNonNfsDirectory(directoryPath: string): Promise { - try { - const stats = await stat(directoryPath); - if (stats.isDirectory()) { - return !(await isNfs(directoryPath)); - } else { - return false; - } - } catch (e) { - // If the directory cannot be probed for whatever reason, just - // indicate that this is not a valid candidate directory. - // Typically this is ENOENT for missing directory. - return false; - } -} - -/** - * Promisified wrappers around fs-plus functions. - */ - -function copy(source: string, dest: string): Promise { +function copy(source, dest) { return new Promise((resolve, reject) => { - fsPlus.copy(source, dest, (err, result) => { + (_fsPlus || _load_fsPlus()).default.copy(source, dest, (err, result) => { if (err == null) { resolve(result); } else { @@ -227,9 +299,9 @@ function copy(source: string, dest: string): Promise { }); } -function move(source: string, dest: string): Promise { +function move(source, dest) { return new Promise((resolve, reject) => { - fsPlus.move(source, dest, (err, result) => { + (_fsPlus || _load_fsPlus()).default.move(source, dest, (err, result) => { if (err == null) { resolve(result); } else { @@ -243,13 +315,9 @@ function move(source: string, dest: string): Promise { * TODO: the fs-plus `writeFile` implementation runs `mkdirp` first. * We should use `fs.writeFile` and have callsites explicitly opt-in to this behaviour. */ -function writeFile( - filename: string, - data: Buffer | string, - options?: Object | string, -): Promise { +function writeFile(filename, data, options) { return new Promise((resolve, reject) => { - fsPlus.writeFile(filename, data, options, (err, result) => { + (_fsPlus || _load_fsPlus()).default.writeFile(filename, data, options, (err, result) => { if (err == null) { resolve(result); } else { @@ -263,9 +331,9 @@ function writeFile( * Promisified wrappers around fs functions. */ -function chmod(path: string, mode: number | string): Promise { +function chmod(path, mode) { return new Promise((resolve, reject) => { - fs.chmod(path, mode, (err, result) => { + _fs.default.chmod(path, mode, (err, result) => { if (err == null) { resolve(result); } else { @@ -275,9 +343,9 @@ function chmod(path: string, mode: number | string): Promise { }); } -function lstat(path: string): Promise { +function lstat(path) { return new Promise((resolve, reject) => { - fs.lstat(path, (err, result) => { + _fs.default.lstat(path, (err, result) => { if (err == null) { resolve(result); } else { @@ -287,9 +355,9 @@ function lstat(path: string): Promise { }); } -function mkdir(path: string, mode?: number): Promise { +function mkdir(path, mode) { return new Promise((resolve, reject) => { - fs.mkdir(path, mode, (err, result) => { + _fs.default.mkdir(path, mode, (err, result) => { if (err == null) { resolve(result); } else { @@ -301,16 +369,12 @@ function mkdir(path: string, mode?: number): Promise { // `fs.readFile` returns a Buffer unless an encoding is specified. // This workaround is adapted from the Flow declarations. -type ReadFileType = - ((filename: string, encoding: string) => Promise) & - ((filename: string, options: { encoding: string, flag?: string }) => Promise) & - ((filename: string) => Promise) & - ((filename: string, options: { flag?: string }) => Promise); -const readFile: ReadFileType = (function() { + +const readFile = function () { return new Promise((resolve, reject) => { // $FlowIssue: spread operator doesn't preserve any-type - fs.readFile(...arguments, (err, result) => { + _fs.default.readFile(...arguments, (err, result) => { if (err == null) { resolve(result); } else { @@ -318,11 +382,11 @@ const readFile: ReadFileType = (function() { } }); }); -}: any); +}; -function readdir(path: string): Promise> { +function readdir(path) { return new Promise((resolve, reject) => { - fs.readdir(path, (err, result) => { + _fs.default.readdir(path, (err, result) => { if (err == null) { resolve(result); } else { @@ -332,9 +396,9 @@ function readdir(path: string): Promise> { }); } -function readlink(path: string): Promise { +function readlink(path) { return new Promise((resolve, reject) => { - fs.readlink(path, (err, result) => { + _fs.default.readlink(path, (err, result) => { if (err == null) { resolve(result); } else { @@ -344,9 +408,9 @@ function readlink(path: string): Promise { }); } -function realpath(path: string, cache?: Object): Promise { +function realpath(path, cache) { return new Promise((resolve, reject) => { - fs.realpath(path, cache, (err, result) => { + _fs.default.realpath(path, cache, (err, result) => { if (err == null) { resolve(result); } else { @@ -356,9 +420,9 @@ function realpath(path: string, cache?: Object): Promise { }); } -function rename(oldPath: string, newPath: string): Promise { +function rename(oldPath, newPath) { return new Promise((resolve, reject) => { - fs.rename(oldPath, newPath, (err, result) => { + _fs.default.rename(oldPath, newPath, (err, result) => { if (err == null) { resolve(result); } else { @@ -368,9 +432,9 @@ function rename(oldPath: string, newPath: string): Promise { }); } -function stat(path: string): Promise { +function stat(path) { return new Promise((resolve, reject) => { - fs.stat(path, (err, result) => { + _fs.default.stat(path, (err, result) => { if (err == null) { resolve(result); } else { @@ -380,9 +444,9 @@ function stat(path: string): Promise { }); } -function symlink(source: string, dest: string, type?: string): Promise { +function symlink(source, dest, type) { return new Promise((resolve, reject) => { - fs.symlink(source, dest, type, (err, result) => { + _fs.default.symlink(source, dest, type, (err, result) => { if (err == null) { resolve(result); } else { @@ -392,9 +456,9 @@ function symlink(source: string, dest: string, type?: string): Promise { }); } -function unlink(path: string): Promise { +function unlink(path) { return new Promise((resolve, reject) => { - fs.unlink(path, (err, result) => { + _fs.default.unlink(path, (err, result) => { if (err == null) { resolve(result); } else { @@ -404,7 +468,7 @@ function unlink(path: string): Promise { }); } -export default { +exports.default = { tempdir, tempfile, findNearestFile, @@ -431,5 +495,6 @@ export default { rename, stat, symlink, - unlink, + unlink }; +module.exports = exports['default']; \ No newline at end of file diff --git a/pkg/commons-node/humanizeKeystroke.js b/pkg/commons-node/humanizeKeystroke.js index b670c96b01..463facda9e 100644 --- a/pkg/commons-node/humanizeKeystroke.js +++ b/pkg/commons-node/humanizeKeystroke.js @@ -1,3 +1,9 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = humanizeKeystroke; /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,7 +11,7 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * */ /* @@ -22,7 +28,7 @@ const MAC_MODIFIER_KEYMAP = { option: '\u2325', right: '\u2192', shift: '\u21e7', - up: '\u2191', + up: '\u2191' }; const NON_MAC_MODIFIER_KEYMAP = { @@ -35,7 +41,7 @@ const NON_MAC_MODIFIER_KEYMAP = { option: 'Alt', right: 'Right', shift: 'Shift', - up: 'Up', + up: 'Up' }; // Human key combos should always explicitly state the shift key. This map is a disambiguator. @@ -51,13 +57,13 @@ const SHIFT_KEYMAP = { '<': ',', '>': '.', '|': '\\', - '~': '`', + '~': '`' }; const FN_KEY_RE = /f[0-9]{1,2}/; // $FlowIssue -function flatten(arr: Array>): Array { +function flatten(arr) { let flattened = []; for (const el of arr) { if (Array.isArray(el)) { @@ -69,13 +75,13 @@ function flatten(arr: Array>): Array { return flattened; } -function capitalize(word: string): string { +function capitalize(word) { const first = word[0] || ''; const rest = word.slice(1); return first.toUpperCase() + rest; } -function humanizeKey(key: string, platform: ?string): string | Array { +function humanizeKey(key, platform) { if (!key) { return key; } @@ -108,7 +114,7 @@ function humanizeKey(key: string, platform: ?string): string | Array { * @param platform An optional String platform to humanize for (default: `process.platform`). * @return a humanized representation of the keystroke. */ -export default function humanizeKeystroke(keystroke: string, platform_: ?string): string { +function humanizeKeystroke(keystroke, platform_) { let platform = platform_; if (!keystroke) { return keystroke; @@ -138,3 +144,4 @@ export default function humanizeKeystroke(keystroke: string, platform_: ?string) } return humanizedKeystrokes.join(' '); } +module.exports = exports['default']; \ No newline at end of file diff --git a/pkg/commons-node/memoizeUntilChanged.js b/pkg/commons-node/memoizeUntilChanged.js index 151e76f5d7..b699dbdb20 100644 --- a/pkg/commons-node/memoizeUntilChanged.js +++ b/pkg/commons-node/memoizeUntilChanged.js @@ -1,3 +1,24 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = memoizeUntilChanged; + +var _collection; + +function _load_collection() { + return _collection = require('./collection'); +} + +var _Hasher; + +function _load_Hasher() { + return _Hasher = _interopRequireDefault(require('./Hasher')); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,15 +26,9 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * */ -import {arrayEqual} from './collection'; -import Hasher from './Hasher'; - -type CompareFunc = (a: Array, b: Array) => boolean; -type KeySelector = (x: T) => U; - const NOTHING = Symbol('nothing'); /** @@ -33,16 +48,12 @@ const NOTHING = Symbol('nothing'); * } * } */ -export default function memoizeUntilChanged( - func: T, - keySelector_?: KeySelector, - compareKeys: CompareFunc = arrayEqual, -): T { +function memoizeUntilChanged(func, keySelector_, compareKeys = (_collection || _load_collection()).arrayEqual) { let prevArgKeys; let prevResult = NOTHING; - const keySelector: KeySelector = keySelector_ || createKeySelector(); + const keySelector = keySelector_ || createKeySelector(); // $FlowIssue: Flow can't express that we want the args to be the same type as the input func's. - return function(...args) { + return function (...args) { const argKeys = args.map(keySelector); if (prevResult === NOTHING || !compareKeys(argKeys, prevArgKeys)) { prevArgKeys = argKeys; @@ -52,7 +63,8 @@ export default function memoizeUntilChanged( }; } -function createKeySelector(): KeySelector { - const hasher: Hasher = new Hasher(); +function createKeySelector() { + const hasher = new (_Hasher || _load_Hasher()).default(); return x => hasher.getHash(x); } +module.exports = exports['default']; \ No newline at end of file diff --git a/pkg/commons-node/nice.js b/pkg/commons-node/nice.js index 5e0029d98e..7735ca3977 100644 --- a/pkg/commons-node/nice.js +++ b/pkg/commons-node/nice.js @@ -1,108 +1,133 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the license found in the LICENSE file in - * the root directory of this source tree. - * - * @flow - */ - -import type {LRUCache} from 'lru-cache'; - -import type { - AsyncExecuteOptions, - AsyncExecuteReturn, -} from './process'; - -import LRU from 'lru-cache'; - -import { - safeSpawn, - asyncExecute, - checkOutput, -} from './process'; - -import which from './which'; - -const NICE_COMMAND = 'nice'; -const IONICE_COMMAND = 'ionice'; +'use strict'; -export async function niceSafeSpawn( - command: string, - args: Array, - execOptions?: Object, -): Promise { - const nicified = await nicifyCommand(command, args); - return safeSpawn(nicified.command, nicified.args, execOptions); -} +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.niceAsyncExecute = exports.niceCheckOutput = exports.niceSafeSpawn = undefined; + +var _asyncToGenerator = _interopRequireDefault(require('async-to-generator')); + +let niceSafeSpawn = exports.niceSafeSpawn = (() => { + var _ref = (0, _asyncToGenerator.default)(function* (command, args, execOptions) { + const nicified = yield nicifyCommand(command, args); + return (0, (_process || _load_process()).safeSpawn)(nicified.command, nicified.args, execOptions); + }); + + return function niceSafeSpawn(_x, _x2, _x3) { + return _ref.apply(this, arguments); + }; +})(); + +let niceCheckOutput = exports.niceCheckOutput = (() => { + var _ref2 = (0, _asyncToGenerator.default)(function* (command, args, execOptions) { + const nicified = yield nicifyCommand(command, args); + return (0, (_process || _load_process()).checkOutput)(nicified.command, nicified.args, execOptions); + }); + + return function niceCheckOutput(_x4, _x5, _x6) { + return _ref2.apply(this, arguments); + }; +})(); + +let niceAsyncExecute = exports.niceAsyncExecute = (() => { + var _ref3 = (0, _asyncToGenerator.default)(function* (command, args, execOptions) { + const nicified = yield nicifyCommand(command, args); + return (0, (_process || _load_process()).asyncExecute)(nicified.command, nicified.args, execOptions); + }); + + return function niceAsyncExecute(_x7, _x8, _x9) { + return _ref3.apply(this, arguments); + }; +})(); + +let nicifyCommand = (() => { + var _ref4 = (0, _asyncToGenerator.default)(function* (command, args) { + const fullArgs = [command, ...args]; + if (yield hasNiceCommand()) { + fullArgs.unshift(NICE_COMMAND); + } + if (yield hasIoniceCommand()) { + // Leave the process in the Best Effort class (default), but set it to the lowest priority for + // that class. Priorities range from 0-7 with 4 as the default and lower numbers representing + // higher priorities. + // + // See `man ionice` or http://linux.die.net/man/1/ionice + // + // It's not specified by POSIX like `nice` is but since it is included in util-linux which is + // relatively core + // (https://git.kernel.org/cgit/utils/util-linux/util-linux.git/tree/schedutils/ionice.c), I + // think we can assume that it uses this interface if it exists. + fullArgs.unshift(IONICE_COMMAND, '-n', '7'); + } + return { + command: fullArgs[0], + args: fullArgs.slice(1) + }; + }); + + return function nicifyCommand(_x10, _x11) { + return _ref4.apply(this, arguments); + }; +})(); -export async function niceCheckOutput( - command: string, - args: Array, - execOptions?: AsyncExecuteOptions, -): Promise { - const nicified = await nicifyCommand(command, args); - return checkOutput(nicified.command, nicified.args, execOptions); +let hasCommand = (() => { + var _ref5 = (0, _asyncToGenerator.default)(function* (command) { + let result = commandAvailabilityCache.get(command); + if (result == null) { + result = (yield (0, (_which || _load_which()).default)(command)) != null; + commandAvailabilityCache.set(command, result); + } + return result; + }); + + return function hasCommand(_x12) { + return _ref5.apply(this, arguments); + }; +})(); + +var _lruCache; + +function _load_lruCache() { + return _lruCache = _interopRequireDefault(require('lru-cache')); } -export async function niceAsyncExecute( - command: string, - args: Array, - execOptions?: AsyncExecuteOptions, -): Promise { - const nicified = await nicifyCommand(command, args); - return asyncExecute(nicified.command, nicified.args, execOptions); +var _process; + +function _load_process() { + return _process = require('./process'); } -async function nicifyCommand( - command: string, - args: Array, -): Promise<{command: string, args: Array}> { - const fullArgs = [command, ...args]; - if (await hasNiceCommand()) { - fullArgs.unshift(NICE_COMMAND); - } - if (await hasIoniceCommand()) { - // Leave the process in the Best Effort class (default), but set it to the lowest priority for - // that class. Priorities range from 0-7 with 4 as the default and lower numbers representing - // higher priorities. - // - // See `man ionice` or http://linux.die.net/man/1/ionice - // - // It's not specified by POSIX like `nice` is but since it is included in util-linux which is - // relatively core - // (https://git.kernel.org/cgit/utils/util-linux/util-linux.git/tree/schedutils/ionice.c), I - // think we can assume that it uses this interface if it exists. - fullArgs.unshift(IONICE_COMMAND, '-n', '7'); - } - return { - command: fullArgs[0], - args: fullArgs.slice(1), - }; +var _which; + +function _load_which() { + return _which = _interopRequireDefault(require('./which')); } -const commandAvailabilityCache: LRUCache = LRU({ +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const NICE_COMMAND = 'nice'; /** + * Copyright (c) 2015-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the license found in the LICENSE file in + * the root directory of this source tree. + * + * + */ + +const IONICE_COMMAND = 'ionice'; + +const commandAvailabilityCache = (0, (_lruCache || _load_lruCache()).default)({ max: 10, // Realistically this will not change very often so we can cache for long periods of time. We // probably could just check at startup and get away with it, but maybe someone will install // `ionice` and it would be nice to pick that up. - maxAge: 1000 * 60 * 5, // 5 minutes -}); + maxAge: 1000 * 60 * 5 }); -function hasNiceCommand(): Promise { +function hasNiceCommand() { return hasCommand(NICE_COMMAND); } -function hasIoniceCommand(): Promise { +function hasIoniceCommand() { return hasCommand(IONICE_COMMAND); -} - -async function hasCommand(command: string): Promise { - let result: ?boolean = commandAvailabilityCache.get(command); - if (result == null) { - result = await which(command) != null; - commandAvailabilityCache.set(command, result); - } - return result; -} +} \ No newline at end of file diff --git a/pkg/commons-node/nuclideUri.js b/pkg/commons-node/nuclideUri.js index 5071c27c01..65153dc0c0 100644 --- a/pkg/commons-node/nuclideUri.js +++ b/pkg/commons-node/nuclideUri.js @@ -1,3 +1,22 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.__TEST__ = undefined; + +var _path = _interopRequireDefault(require('path')); + +var _url = _interopRequireDefault(require('url')); + +var _string; + +function _load_string() { + return _string = require('./string'); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,7 +24,7 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * */ // NuclideUri's are either a local file path, or a URI @@ -13,63 +32,40 @@ // // This package creates, queries and decomposes NuclideUris. -export type NuclideUri = string; - -type ParsedUrl = { - hostname: ?string, - path: string, -}; - -type ParsedRemoteUrl = { - hostname: string, - path: string, -}; - -type ParsedPath = { - root: string, - dir: string, - base: string, - ext: string, - name: string, -}; - -import invariant from 'assert'; +const REMOTE_PATH_URI_PREFIX = 'nuclide://'; // eslint-disable-next-line nuclide-internal/prefer-nuclide-uri -import pathModule from 'path'; -import url from 'url'; - -import {maybeToString} from './string'; - -const REMOTE_PATH_URI_PREFIX = 'nuclide://'; const URI_PREFIX_REGEX = /^[A-Za-z0-9_-]+:\/\/.*/; -function isRemote(uri: NuclideUri): boolean { +function isRemote(uri) { return uri.startsWith(REMOTE_PATH_URI_PREFIX); } // When restoring Atom state on load, Atom mangles our remote URIs by // removing one of the '/'s. These TextBuffers/TextEditors live for a short time // and are destroyed during Nuclide startup. -function isBrokenDeserializedUri(uri: ?NuclideUri): boolean { +function isBrokenDeserializedUri(uri) { return uri != null && uri.match(/nuclide:[\\/][^/]/) != null; } // Atom often puts its URIs in places where we'd expect to see Nuclide URIs (or plain paths) -function isAtomUri(uri: NuclideUri): boolean { +function isAtomUri(uri) { return uri.startsWith('atom://'); } -function isUri(uri: string): boolean { +function isUri(uri) { return URI_PREFIX_REGEX.test(uri); } -function isLocal(uri: NuclideUri): boolean { +function isLocal(uri) { return !isRemote(uri) && !isUri(uri) && !isAtomUri(uri); } -function createRemoteUri(hostname: string, remotePath: string): string { - invariant(remotePath != null && remotePath !== '', 'NuclideUri must include a path.'); +function createRemoteUri(hostname, remotePath) { + if (!(remotePath != null && remotePath !== '')) { + throw new Error('NuclideUri must include a path.'); + } + return `nuclide://${hostname}${remotePath}`; } @@ -82,62 +78,61 @@ function createRemoteUri(hostname: string, remotePath: string): string { * Everything that does not contain a '://' is assumed to be a local path. Both POSIX and Windows * paths are legal */ -function parse(uri: NuclideUri): ParsedUrl { +function parse(uri) { if (uri.startsWith(REMOTE_PATH_URI_PREFIX)) { const hostAndPath = uri.substr(REMOTE_PATH_URI_PREFIX.length); const hostSep = hostAndPath.indexOf('/'); - invariant( - hostSep !== -1, - `Remote URIs must contain a hostname and a path. Failed to parse ${uri}`, - ); + if (!(hostSep !== -1)) { + throw new Error(`Remote URIs must contain a hostname and a path. Failed to parse ${uri}`); + } const hostname = hostAndPath.substr(0, hostSep); - invariant( - hostname !== '', - `Remote URIs must contain a hostname. Failed to parse ${uri}`, - ); + + if (!(hostname !== '')) { + throw new Error(`Remote URIs must contain a hostname. Failed to parse ${uri}`); + } const path = hostAndPath.substr(hostSep); - return {hostname, path}; + return { hostname, path }; } - invariant( - uri.indexOf('://') === -1, - 'Nuclide URI must be either local file names or URLs starting with nuclide://', - ); + if (!(uri.indexOf('://') === -1)) { + throw new Error('Nuclide URI must be either local file names or URLs starting with nuclide://'); + } - return {hostname: null, path: uri}; + return { hostname: null, path: uri }; } -function parseRemoteUri(remoteUri: NuclideUri): ParsedRemoteUrl { +function parseRemoteUri(remoteUri) { if (!isRemote(remoteUri)) { throw new Error('Expected remote uri. Got ' + remoteUri); } const parsedUri = parse(remoteUri); - invariant( - parsedUri.hostname, - `Remote Nuclide URIs must contain hostnames, '${maybeToString(parsedUri.hostname)}' found ` + - `while parsing '${remoteUri}'`, - ); + + if (!parsedUri.hostname) { + throw new Error(`Remote Nuclide URIs must contain hostnames, '${(0, (_string || _load_string()).maybeToString)(parsedUri.hostname)}' found ` + `while parsing '${remoteUri}'`); + } // Explicitly copying object properties appeases Flow's "maybe" type handling. Using the `...` // operator causes null/undefined errors, and `Object.assign` bypasses type checking. + + return { hostname: parsedUri.hostname, - path: parsedUri.path, + path: parsedUri.path }; } -function getPath(uri: NuclideUri): string { +function getPath(uri) { return parse(uri).path; } -function getHostname(remoteUri: NuclideUri): string { +function getHostname(remoteUri) { return parseRemoteUri(remoteUri).hostname; } -function getHostnameOpt(remoteUri: ?NuclideUri): ?string { +function getHostnameOpt(remoteUri) { if (remoteUri == null || !isRemote(remoteUri)) { return null; } @@ -145,50 +140,44 @@ function getHostnameOpt(remoteUri: ?NuclideUri): ?string { return getHostname(remoteUri); } -function join(uri: NuclideUri, ...relativePath: Array): NuclideUri { +function join(uri, ...relativePath) { _testForAtomUri(uri); const uriPathModule = _pathModuleFor(uri); if (isRemote(uri)) { - const {hostname, path} = parseRemoteUri(uri); + const { hostname, path } = parseRemoteUri(uri); relativePath.splice(0, 0, path); - return createRemoteUri( - hostname, - uriPathModule.join.apply(null, relativePath)); + return createRemoteUri(hostname, uriPathModule.join.apply(null, relativePath)); } else { relativePath.splice(0, 0, uri); return uriPathModule.join.apply(null, relativePath); } } -function normalize(uri: NuclideUri): NuclideUri { +function normalize(uri) { _testForAtomUri(uri); const uriPathModule = _pathModuleFor(uri); if (isRemote(uri)) { - const {hostname, path} = parseRemoteUri(uri); - return createRemoteUri( - hostname, - uriPathModule.normalize(path), - ); + const { hostname, path } = parseRemoteUri(uri); + return createRemoteUri(hostname, uriPathModule.normalize(path)); } else { return uriPathModule.normalize(uri); } } -function normalizeDir(uri: NuclideUri): NuclideUri { +function normalizeDir(uri) { return ensureTrailingSeparator(normalize(uri)); } -function getParent(uri: NuclideUri): NuclideUri { +function getParent(uri) { // TODO: Is this different than dirname? return normalize(join(uri, '..')); } -function relative(uri: NuclideUri, other: NuclideUri): string { +function relative(uri, other) { _testForAtomUri(uri); const uriPathModule = _pathModuleFor(uri); const remote = isRemote(uri); - if (remote !== isRemote(other) || - (remote && getHostname(uri) !== getHostname(other))) { + if (remote !== isRemote(other) || remote && getHostname(uri) !== getHostname(other)) { throw new Error(`Cannot relative urls on different hosts: ${uri} and ${other}`); } if (remote) { @@ -198,33 +187,30 @@ function relative(uri: NuclideUri, other: NuclideUri): string { } } -function basename(uri: NuclideUri, ext: string = ''): string { +function basename(uri, ext = '') { _testForAtomUri(uri); const uriPathModule = _pathModuleFor(uri); return uriPathModule.basename(getPath(uri), ext); } -function dirname(uri: NuclideUri): NuclideUri { +function dirname(uri) { _testForAtomUri(uri); const uriPathModule = _pathModuleFor(uri); if (isRemote(uri)) { - const {hostname, path} = parseRemoteUri(uri); - return createRemoteUri( - hostname, - uriPathModule.dirname(path), - ); + const { hostname, path } = parseRemoteUri(uri); + return createRemoteUri(hostname, uriPathModule.dirname(path)); } else { return uriPathModule.dirname(uri); } } -function extname(uri: NuclideUri): string { +function extname(uri) { _testForAtomUri(uri); const uriPathModule = _pathModuleFor(uri); return uriPathModule.extname(getPath(uri)); } -function stripExtension(uri: NuclideUri): NuclideUri { +function stripExtension(uri) { _testForAtomUri(uri); const ext = extname(uri); if (ext.length === 0) { @@ -240,9 +226,10 @@ function stripExtension(uri: NuclideUri): NuclideUri { * * Returns null if not a valid file: URI. */ -function uriToNuclideUri(uri: string): ?string { - const urlParts = url.parse(_escapeSpecialCharacters(uri), false); - if (urlParts.protocol === 'file:' && urlParts.path) { // only handle real files for now. +function uriToNuclideUri(uri) { + const urlParts = _url.default.parse(_escapeSpecialCharacters(uri), false); + if (urlParts.protocol === 'file:' && urlParts.path) { + // only handle real files for now. return urlParts.path; } else if (isRemote(uri)) { return uri; @@ -254,7 +241,7 @@ function uriToNuclideUri(uri: string): ?string { /** * Converts local paths to file: URI's. Leaves remote URI's alone. */ -function nuclideUriToUri(uri: NuclideUri): string { +function nuclideUriToUri(uri) { _testForAtomUri(uri); if (isRemote(uri)) { return uri; @@ -266,7 +253,7 @@ function nuclideUriToUri(uri: NuclideUri): string { /** * Returns true if child is equal to, or is a proper child of parent. */ -function contains(parent: NuclideUri, child: NuclideUri): boolean { +function contains(parent, child) { _testForAtomUri(parent); _testForAtomUri(child); @@ -285,9 +272,11 @@ function contains(parent: NuclideUri, child: NuclideUri): boolean { // equal OR if the next character in the path to check is a path // separator, then we know the checked path is in this path. - if (child.length < parent.length) { // A strong indication of false + if (child.length < parent.length) { + // A strong indication of false // It could be a matter of a trailing separator, though - if (child.length < parent.length - 1) { // It must be more than just the separator + if (child.length < parent.length - 1) { + // It must be more than just the separator return false; } @@ -310,20 +299,18 @@ function contains(parent: NuclideUri, child: NuclideUri): boolean { * Filter an array of paths to contain only the collapsed root paths, e.g. * [a/b/c, a/, c/d/, c/d/e] collapses to [a/, c/d/] */ -function collapse(paths: Array): Array { - return paths.filter(p => - !paths.some(fp => contains(fp, p) && fp !== p), - ); +function collapse(paths) { + return paths.filter(p => !paths.some(fp => contains(fp, p) && fp !== p)); } const hostFormatters = []; // A formatter which may shorten hostnames. // Returns null if the formatter won't shorten the hostname. -export type HostnameFormatter = (uri: NuclideUri) => ?string; + // Registers a host formatter for nuclideUriToDisplayString -function registerHostnameFormatter(formatter: HostnameFormatter): IDisposable { +function registerHostnameFormatter(formatter) { hostFormatters.push(formatter); return { dispose: () => { @@ -331,7 +318,7 @@ function registerHostnameFormatter(formatter: HostnameFormatter): IDisposable { if (index >= 0) { hostFormatters.splice(index, 1); } - }, + } }; } @@ -339,7 +326,7 @@ function registerHostnameFormatter(formatter: HostnameFormatter): IDisposable { * NuclideUris should never be shown to humans. * This function returns a human usable string. */ -function nuclideUriToDisplayString(uri: NuclideUri): string { +function nuclideUriToDisplayString(uri) { _testForAtomUri(uri); if (isRemote(uri)) { let hostname = getHostname(uri); @@ -356,7 +343,7 @@ function nuclideUriToDisplayString(uri: NuclideUri): string { } } -function ensureTrailingSeparator(uri: NuclideUri): NuclideUri { +function ensureTrailingSeparator(uri) { _testForAtomUri(uri); const uriPathModule = _pathModuleFor(uri); if (uri.endsWith(uriPathModule.sep)) { @@ -366,7 +353,7 @@ function ensureTrailingSeparator(uri: NuclideUri): NuclideUri { return uri + uriPathModule.sep; } -function trimTrailingSeparator(uri: NuclideUri): NuclideUri { +function trimTrailingSeparator(uri) { _testForAtomUri(uri); const uriPathModule = _pathModuleFor(uri); let stripped = uri; @@ -378,13 +365,13 @@ function trimTrailingSeparator(uri: NuclideUri): NuclideUri { return stripped; } -function endsWithSeparator(uri: NuclideUri): boolean { +function endsWithSeparator(uri) { _testForAtomUri(uri); const uriPathModule = _pathModuleFor(uri); return uri.endsWith(uriPathModule.sep); } -function isAbsolute(uri: NuclideUri): boolean { +function isAbsolute(uri) { _testForAtomUri(uri); if (isRemote(uri)) { return true; @@ -394,22 +381,20 @@ function isAbsolute(uri: NuclideUri): boolean { } } -function resolve(uri: NuclideUri, ...paths: Array): NuclideUri { +function resolve(uri, ...paths) { _testForAtomUri(uri); const uriPathModule = _pathModuleFor(uri); if (isRemote(uri)) { - const {hostname, path} = parseRemoteUri(uri); + const { hostname, path } = parseRemoteUri(uri); paths.splice(0, 0, path); - return createRemoteUri( - hostname, - uriPathModule.resolve.apply(null, paths)); + return createRemoteUri(hostname, uriPathModule.resolve.apply(null, paths)); } else { paths.splice(0, 0, uri); return uriPathModule.resolve.apply(null, paths); } } -function expandHomeDir(uri: NuclideUri): NuclideUri { +function expandHomeDir(uri) { _testForAtomUri(uri); // This function is POSIX only functionality, so using the posix path directly @@ -418,8 +403,11 @@ function expandHomeDir(uri: NuclideUri): NuclideUri { return uri; } - const {HOME} = process.env; - invariant(HOME != null); + const { HOME } = process.env; + + if (!(HOME != null)) { + throw new Error('Invariant violation: "HOME != null"'); + } if (uri === '~') { return HOME; @@ -430,7 +418,7 @@ function expandHomeDir(uri: NuclideUri): NuclideUri { return uri; } - return pathModule.posix.resolve(HOME, uri.replace('~', '.')); + return _path.default.posix.resolve(HOME, uri.replace('~', '.')); } /** @@ -439,8 +427,11 @@ function expandHomeDir(uri: NuclideUri): NuclideUri { * * Since remote URI might contain the delimiter, only local paths are allowed. */ -function splitPathList(paths: string): Array { - invariant(paths.indexOf(REMOTE_PATH_URI_PREFIX) < 0, 'Splitting remote URIs is not supported'); +function splitPathList(paths) { + if (!(paths.indexOf(REMOTE_PATH_URI_PREFIX) < 0)) { + throw new Error('Splitting remote URIs is not supported'); + } + const uriPathModule = _pathModuleFor(paths); return paths.split(uriPathModule.delimiter); @@ -452,12 +443,14 @@ function splitPathList(paths: string): Array { * * Since remote URI might contain the delimiter, only local paths are allowed. */ -function joinPathList(paths: Array): string { +function joinPathList(paths) { if (paths.length === 0) { return ''; } - invariant(paths.every(path => !isRemote(path)), 'Joining of remote URIs is not supported'); + if (!paths.every(path => !isRemote(path))) { + throw new Error('Joining of remote URIs is not supported'); + } const uriPathModule = _pathModuleFor(paths[0]); return paths.join(uriPathModule.delimiter); @@ -467,12 +460,17 @@ function joinPathList(paths: Array): string { * This function prepends the given relative path with a "current-folder" prefix * which is `./` on *nix and .\ on Windows */ -function ensureLocalPrefix(uri: NuclideUri): NuclideUri { +function ensureLocalPrefix(uri) { _testForAtomUri(uri); const uriPathModule = _pathModuleFor(uri); - invariant(!isRemote(uri), 'Local prefix can not be added to a remote path'); - invariant(!isAbsolute(uri), 'Local prefix can not be added to an absolute path'); + if (!!isRemote(uri)) { + throw new Error('Local prefix can not be added to a remote path'); + } + + if (!!isAbsolute(uri)) { + throw new Error('Local prefix can not be added to an absolute path'); + } const localPrefix = `.${uriPathModule.sep}`; if (uri.startsWith(localPrefix)) { @@ -482,18 +480,18 @@ function ensureLocalPrefix(uri: NuclideUri): NuclideUri { return localPrefix + uri; } -function isRoot(uri: NuclideUri): boolean { +function isRoot(uri) { _testForAtomUri(uri); return dirname(uri) === uri; } -function parsePath(uri: NuclideUri): ParsedPath { +function parsePath(uri) { _testForAtomUri(uri); const uriPathModule = _pathModuleFor(uri); return uriPathModule.parse(getPath(uri)); } -function split(uri: NuclideUri): Array { +function split(uri) { const parts = []; let current = uri; let parent = dirname(current); @@ -512,21 +510,21 @@ function split(uri: NuclideUri): Array { return parts; } -function _pathModuleFor(uri: NuclideUri): typeof pathModule { - if (uri.startsWith(pathModule.posix.sep)) { - return pathModule.posix; +function _pathModuleFor(uri) { + if (uri.startsWith(_path.default.posix.sep)) { + return _path.default.posix; } if (uri.indexOf('://') > -1) { - return pathModule.posix; + return _path.default.posix; } - if (uri[1] === ':' && uri[2] === pathModule.win32.sep) { - return pathModule.win32; + if (uri[1] === ':' && uri[2] === _path.default.win32.sep) { + return _path.default.win32; } - if (uri.split(pathModule.win32.sep).length > uri.split(pathModule.posix.sep).length) { - return pathModule.win32; + if (uri.split(_path.default.win32.sep).length > uri.split(_path.default.posix.sep).length) { + return _path.default.win32; } else { - return pathModule.posix; + return _path.default.posix; } } @@ -535,11 +533,11 @@ function _pathModuleFor(uri: NuclideUri): typeof pathModule { * paths. They, however, are being automatically "corrected" by node's `url.parse()` method if not * escaped properly. */ -function _escapeSpecialCharacters(uri: NuclideUri): NuclideUri { +function _escapeSpecialCharacters(uri) { return uri.replace(/%/g, '%25').replace(/\\/g, '%5C'); } -function _testForAtomUri(uri: ?NuclideUri): void { +function _testForAtomUri(uri) { if (uri != null && isAtomUri(uri)) { throw new Error(`Path operation invoked on Atom URI ${uri}`); } @@ -549,21 +547,34 @@ const NUCLIDE_URI_TYPE_NAME = 'NuclideUri'; // If mustBeRemote is present then remote-ness must match, otherwise remote-ness // is ignored. -function validate(uri: NuclideUri, mustBeRemote?: boolean): void { +function validate(uri, mustBeRemote) { // Be a little extra paranoid to catch places where the type system may be weak. - invariant(uri != null, 'Unexpected null NuclideUri'); - invariant(typeof uri === 'string', `Unexpected NuclideUri type: ${String(uri)}`); + if (!(uri != null)) { + throw new Error('Unexpected null NuclideUri'); + } + + if (!(typeof uri === 'string')) { + throw new Error(`Unexpected NuclideUri type: ${String(uri)}`); + } if (isRemote(uri)) { parse(uri); - invariant(mustBeRemote !== false, 'Expected remote NuclideUri'); + + if (!(mustBeRemote !== false)) { + throw new Error('Expected remote NuclideUri'); + } } else { - invariant(uri !== '', 'NuclideUri must contain a non-empty path'); - invariant(mustBeRemote !== true, 'Expected local NuclideUri'); + if (!(uri !== '')) { + throw new Error('NuclideUri must contain a non-empty path'); + } + + if (!(mustBeRemote !== true)) { + throw new Error('Expected local NuclideUri'); + } } } -export default { +exports.default = { basename, dirname, extname, @@ -601,9 +612,8 @@ export default { isRoot, parsePath, split, - NUCLIDE_URI_TYPE_NAME, -}; - -export const __TEST__ = { - _pathModuleFor, + NUCLIDE_URI_TYPE_NAME }; +const __TEST__ = exports.__TEST__ = { + _pathModuleFor +}; \ No newline at end of file diff --git a/pkg/commons-node/observable.js b/pkg/commons-node/observable.js index 19854aea25..751ee9a7c1 100644 --- a/pkg/commons-node/observable.js +++ b/pkg/commons-node/observable.js @@ -1,19 +1,36 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the license found in the LICENSE file in - * the root directory of this source tree. - * - * @flow - */ +'use strict'; -/* global requestAnimationFrame, cancelAnimationFrame */ +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.nextAnimationFrame = exports.nextTick = undefined; +exports.splitStream = splitStream; +exports.bufferUntil = bufferUntil; +exports.cacheWhileSubscribed = cacheWhileSubscribed; +exports.diffSets = diffSets; +exports.reconcileSetDiffs = reconcileSetDiffs; +exports.reconcileSets = reconcileSets; +exports.toggle = toggle; +exports.compact = compact; +exports.takeWhileInclusive = takeWhileInclusive; +exports.concatLatest = concatLatest; +exports.throttle = throttle; -import UniversalDisposable from './UniversalDisposable'; -import invariant from 'assert'; -import {setDifference} from './collection'; -import {Observable, ReplaySubject} from 'rxjs'; +var _UniversalDisposable; + +function _load_UniversalDisposable() { + return _UniversalDisposable = _interopRequireDefault(require('./UniversalDisposable')); +} + +var _collection; + +function _load_collection() { + return _collection = require('./collection'); +} + +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js'); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /** * Splits a stream of strings on newlines. @@ -21,9 +38,9 @@ import {Observable, ReplaySubject} from 'rxjs'; * Sends any non-newline terminated data before closing. * Never sends an empty string. */ -export function splitStream(input: Observable): Observable { - return Observable.create(observer => { - let current: string = ''; +function splitStream(input) { + return _rxjsBundlesRxMinJs.Observable.create(observer => { + let current = ''; function onEnd() { if (current !== '') { @@ -32,25 +49,34 @@ export function splitStream(input: Observable): Observable { } } - return input.subscribe( - value => { - const lines = (current + value).split('\n'); - current = lines.pop(); - lines.forEach(line => observer.next(line + '\n')); - }, - error => { onEnd(); observer.error(error); }, - () => { onEnd(); observer.complete(); }, - ); + return input.subscribe(value => { + const lines = (current + value).split('\n'); + current = lines.pop(); + lines.forEach(line => observer.next(line + '\n')); + }, error => { + onEnd();observer.error(error); + }, () => { + onEnd();observer.complete(); + }); }); } // TODO: We used to use `stream.buffer(stream.filter(...))` for this but it doesn't work in RxJS 5. // See https://github.com/ReactiveX/rxjs/issues/1610 -export function bufferUntil( - stream: Observable, - condition: (item: T) => boolean, -): Observable> { - return Observable.create(observer => { +/** + * Copyright (c) 2015-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the license found in the LICENSE file in + * the root directory of this source tree. + * + * + */ + +/* global requestAnimationFrame, cancelAnimationFrame */ + +function bufferUntil(stream, condition) { + return _rxjsBundlesRxMinJs.Observable.create(observer => { let buffer = null; const flush = () => { if (buffer != null) { @@ -58,26 +84,21 @@ export function bufferUntil( buffer = null; } }; - return stream - .subscribe( - x => { - if (buffer == null) { - buffer = []; - } - buffer.push(x); - if (condition(x)) { - flush(); - } - }, - err => { - flush(); - observer.error(err); - }, - () => { - flush(); - observer.complete(); - }, - ); + return stream.subscribe(x => { + if (buffer == null) { + buffer = []; + } + buffer.push(x); + if (condition(x)) { + flush(); + } + }, err => { + flush(); + observer.error(err); + }, () => { + flush(); + observer.complete(); + }); }); } @@ -89,64 +110,55 @@ export function bufferUntil( * be just fine because the hot Observable will continue producing values even when there are no * subscribers, so you can be assured that the cached values are up-to-date. */ -export function cacheWhileSubscribed(input: Observable): Observable { - return input.multicast(() => new ReplaySubject(1)).refCount(); +function cacheWhileSubscribed(input) { + return input.multicast(() => new _rxjsBundlesRxMinJs.ReplaySubject(1)).refCount(); } -type Diff = { - added: Set, - removed: Set, -}; - /** * Given a stream of sets, return a stream of diffs. * **IMPORTANT:** These sets are assumed to be immutable by convention. Don't mutate them! */ -export function diffSets(sets: Observable>, hash?: (v: T) => any): Observable> { - return Observable.concat( - Observable.of(new Set()), // Always start with no items with an empty set - sets, - ) - .pairwise() - .map(([previous, next]) => ({ - added: setDifference(next, previous, hash), - removed: setDifference(previous, next, hash), - })) - .filter(diff => diff.added.size > 0 || diff.removed.size > 0); +function diffSets(sets, hash) { + return _rxjsBundlesRxMinJs.Observable.concat(_rxjsBundlesRxMinJs.Observable.of(new Set()), // Always start with no items with an empty set + sets).pairwise().map(([previous, next]) => ({ + added: (0, (_collection || _load_collection()).setDifference)(next, previous, hash), + removed: (0, (_collection || _load_collection()).setDifference)(previous, next, hash) + })).filter(diff => diff.added.size > 0 || diff.removed.size > 0); } /** * Give a stream of diffs, perform an action for each added item and dispose of the returned * disposable when the item is removed. */ -export function reconcileSetDiffs( - diffs: Observable>, - addAction: (addedItem: T) => IDisposable, - hash_?: (v: T) => any, -): IDisposable { +function reconcileSetDiffs(diffs, addAction, hash_) { const hash = hash_ || (x => x); const itemsToDisposables = new Map(); const disposeItem = item => { const disposable = itemsToDisposables.get(hash(item)); - invariant(disposable != null); + + if (!(disposable != null)) { + throw new Error('Invariant violation: "disposable != null"'); + } + disposable.dispose(); itemsToDisposables.delete(item); }; const disposeAll = () => { - itemsToDisposables.forEach(disposable => { disposable.dispose(); }); + itemsToDisposables.forEach(disposable => { + disposable.dispose(); + }); itemsToDisposables.clear(); }; - return new UniversalDisposable( - diffs.subscribe(diff => { - // For every item that got added, perform the add action. - diff.added.forEach(item => { itemsToDisposables.set(hash(item), addAction(item)); }); + return new (_UniversalDisposable || _load_UniversalDisposable()).default(diffs.subscribe(diff => { + // For every item that got added, perform the add action. + diff.added.forEach(item => { + itemsToDisposables.set(hash(item), addAction(item)); + }); - // "Undo" the add action for each item that got removed. - diff.removed.forEach(disposeItem); - }), - disposeAll, - ); + // "Undo" the add action for each item that got removed. + diff.removed.forEach(disposeItem); + }), disposeAll); } /** @@ -177,85 +189,51 @@ export function reconcileSetDiffs( * of the dogs observable, his notification will remain until `disposable.dispose()` is called, at * which point the cleanup for all remaining items will be performed. */ -export function reconcileSets( - sets: Observable>, - addAction: (addedItem: T) => IDisposable, - hash?: (v: T) => any, -): IDisposable { +function reconcileSets(sets, addAction, hash) { const diffs = diffSets(sets, hash); return reconcileSetDiffs(diffs, addAction, hash); } -export function toggle( - source: Observable, - toggler: Observable, -): Observable { - return toggler - .distinctUntilChanged() - .switchMap(enabled => (enabled ? source : Observable.empty())); +function toggle(source, toggler) { + return toggler.distinctUntilChanged().switchMap(enabled => enabled ? source : _rxjsBundlesRxMinJs.Observable.empty()); } -export function compact(source: Observable): Observable { +function compact(source) { // Flow does not understand the semantics of `filter` - return (source.filter(x => x != null): any); + return source.filter(x => x != null); } /** * Like `takeWhile`, but includes the first item that doesn't match the predicate. */ -export function takeWhileInclusive( - source: Observable, - predicate: (value: T) => boolean, -): Observable { - return Observable.create(observer => ( - source.subscribe( - x => { - observer.next(x); - if (!predicate(x)) { - observer.complete(); - } - }, - err => { observer.error(err); }, - () => { observer.complete(); }, - ) - )); +function takeWhileInclusive(source, predicate) { + return _rxjsBundlesRxMinJs.Observable.create(observer => source.subscribe(x => { + observer.next(x); + if (!predicate(x)) { + observer.complete(); + } + }, err => { + observer.error(err); + }, () => { + observer.complete(); + })); } // Concatenate the latest values from each input observable into one big list. // Observables who have not emitted a value yet are treated as empty. -export function concatLatest( - ...observables: Array>> -): Observable> { +function concatLatest(...observables) { // First, tag all input observables with their index. - // Flow errors with ambiguity without the explicit annotation. - const tagged: Array, number]>> = observables.map( - (observable, index) => observable.map(list => [list, index]), - ); - return Observable - .merge(...tagged) - .scan( - (accumulator, [list, index]) => { - accumulator[index] = list; - return accumulator; - }, - observables.map(x => []), - ) - .map(accumulator => [].concat(...accumulator)); + const tagged = observables.map((observable, index) => observable.map(list => [list, index])); + return _rxjsBundlesRxMinJs.Observable.merge(...tagged).scan((accumulator, [list, index]) => { + accumulator[index] = list; + return accumulator; + }, observables.map(x => [])).map(accumulator => [].concat(...accumulator)); } -type ThrottleOptions = { - // Should the first element be emitted immeditately? Defaults to true. - leading?: boolean, -}; - /** * A more sensible alternative to RxJS's throttle/audit/sample operators. */ -export function throttle( - source: Observable, - duration: number | Observable | (value: T) => Observable | Promise, - options_: ?ThrottleOptions, -): Observable { +function throttle(source, duration, options_) { const options = options_ || {}; const leading = options.leading !== false; let audit; @@ -275,24 +253,21 @@ export function throttle( return audit(source); } - return Observable.create(observer => { + return _rxjsBundlesRxMinJs.Observable.create(observer => { const connectableSource = source.publish(); - const throttled = Observable.merge(connectableSource.take(1), audit(connectableSource.skip(1))); - return new UniversalDisposable( - throttled.subscribe(observer), - connectableSource.connect(), - ); + const throttled = _rxjsBundlesRxMinJs.Observable.merge(connectableSource.take(1), audit(connectableSource.skip(1))); + return new (_UniversalDisposable || _load_UniversalDisposable()).default(throttled.subscribe(observer), connectableSource.connect()); }); } -export const nextTick = Observable.create(observer => { +const nextTick = exports.nextTick = _rxjsBundlesRxMinJs.Observable.create(observer => { process.nextTick(() => { observer.next(); observer.complete(); }); }); -export const nextAnimationFrame = Observable.create(observer => { +const nextAnimationFrame = exports.nextAnimationFrame = _rxjsBundlesRxMinJs.Observable.create(observer => { if (typeof requestAnimationFrame === 'undefined') { throw new Error('This util can only be used in Atom'); } @@ -300,5 +275,7 @@ export const nextAnimationFrame = Observable.create(observer => { observer.next(); observer.complete(); }); - return () => { cancelAnimationFrame(id); }; -}); + return () => { + cancelAnimationFrame(id); + }; +}); \ No newline at end of file diff --git a/pkg/commons-node/once.js b/pkg/commons-node/once.js index aff3c2ae7d..5c248877cc 100644 --- a/pkg/commons-node/once.js +++ b/pkg/commons-node/once.js @@ -1,3 +1,9 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = once; /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,17 +11,17 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * */ -export default function once(fn: () => T): () => T { - let fnMaybe: ?(() => T) = fn; - let ret: ?T; - return function(): T { +function once(fn) { + let fnMaybe = fn; + let ret; + return function () { // The type gymnastics here are so `fn` can be // garbage collected once we've used it. if (!fnMaybe) { - return (ret: any); + return ret; } else { ret = fnMaybe.apply(this, arguments); fnMaybe = null; @@ -23,3 +29,4 @@ export default function once(fn: () => T): () => T { } }; } +module.exports = exports["default"]; \ No newline at end of file diff --git a/pkg/commons-node/passesGK.js b/pkg/commons-node/passesGK.js index 132a8d6d69..d84befcef0 100644 --- a/pkg/commons-node/passesGK.js +++ b/pkg/commons-node/passesGK.js @@ -1,3 +1,32 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _asyncToGenerator = _interopRequireDefault(require('async-to-generator')); + +exports.isGkEnabled = isGkEnabled; +exports.onceGkInitialized = onceGkInitialized; + +var _once; + +function _load_once() { + return _once = _interopRequireDefault(require('./once')); +} + +var _eventKit; + +function _load_eventKit() { + return _eventKit = require('event-kit'); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/** + * Get the actual Gatekeeper constructor or stub the relevant methods for OSS + * friendliness. + */ /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,32 +34,27 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * */ -import once from './once'; -import {Disposable} from 'event-kit'; - -/** - * Get the actual Gatekeeper constructor or stub the relevant methods for OSS - * friendliness. - */ -const getGatekeeper = once(() => { +const getGatekeeper = (0, (_once || _load_once()).default)(() => { let Gatekeeper; try { // $FlowFB Gatekeeper = require('./fb-gatekeeper').Gatekeeper; } catch (e) { Gatekeeper = class { - isGkEnabled(): ?boolean { + isGkEnabled() { return null; } - asyncIsGkEnabled(): Promise { + asyncIsGkEnabled() { return Promise.resolve(); } - onceGkInitialized(callback: () => mixed): IDisposable { - process.nextTick(() => { callback(); }); - return new Disposable(); + onceGkInitialized(callback) { + process.nextTick(() => { + callback(); + }); + return new (_eventKit || _load_eventKit()).Disposable(); } }; } @@ -40,30 +64,33 @@ const getGatekeeper = once(() => { /** * Check a GK. Silently return false on error. */ -export default async function passesGK( - name: string, - timeout?: number, -): Promise { - try { - return (await getGatekeeper().asyncIsGkEnabled(name, timeout)) === true; - } catch (e) { - return false; + +exports.default = (() => { + var _ref = (0, _asyncToGenerator.default)(function* (name, timeout) { + try { + return (yield getGatekeeper().asyncIsGkEnabled(name, timeout)) === true; + } catch (e) { + return false; + } + }); + + function passesGK(_x, _x2) { + return _ref.apply(this, arguments); } -} + + return passesGK; +})(); /** * Synchronous GK check. There is no guarantee that GKs have loaded. This * should be used inside a `onceGkInitialized`. */ -export function isGkEnabled( - name: string, -): ?boolean { + + +function isGkEnabled(name) { return getGatekeeper().isGkEnabled(name); } -export function onceGkInitialized( - callback: () => mixed, - timeout?: number, -): IDisposable { +function onceGkInitialized(callback, timeout) { return getGatekeeper().onceGkInitialized(callback, timeout); -} +} \ No newline at end of file diff --git a/pkg/commons-node/performanceNow.js b/pkg/commons-node/performanceNow.js index 6b17a72c09..a2efcba4ea 100644 --- a/pkg/commons-node/performanceNow.js +++ b/pkg/commons-node/performanceNow.js @@ -1,3 +1,8 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,7 +10,7 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * */ /* global performance */ @@ -20,11 +25,8 @@ * const timeItTookInMilliseconds = performanceNow() - now; */ -export default ( - typeof performance !== 'undefined' - ? (): number => performance.now() - : (): number => { - const [seconds, nanoseconds] = process.hrtime(); - return seconds * 1000 + nanoseconds / 1000000; - } -); +exports.default = typeof performance !== 'undefined' ? () => performance.now() : () => { + const [seconds, nanoseconds] = process.hrtime(); + return seconds * 1000 + nanoseconds / 1000000; +}; +module.exports = exports['default']; \ No newline at end of file diff --git a/pkg/commons-node/process-rpc-types.js b/pkg/commons-node/process-rpc-types.js index ef72ba9809..a726efc43f 100644 --- a/pkg/commons-node/process-rpc-types.js +++ b/pkg/commons-node/process-rpc-types.js @@ -1,35 +1 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the license found in the LICENSE file in - * the root directory of this source tree. - * - * @flow - */ - -// Exactly one of exitCode and signal will be non-null. -// Killing a process will result in a null exitCode but a non-null signal. -export type ProcessExitMessage = { - kind: 'exit', - exitCode: ?number, - signal: ?string, -}; - -// Separated out for RPC usage. -export type ProcessMessage = { - kind: 'stdout', - data: string, -} | { - kind: 'stderr', - data: string, -} | ProcessExitMessage | { - kind: 'error', - error: Object, -}; - -export type ProcessInfo = { - parentPid: number, - pid: number, - command: string, -}; +'use strict'; \ No newline at end of file diff --git a/pkg/commons-node/process.js b/pkg/commons-node/process.js index ce1f49009e..0e103d95b4 100644 --- a/pkg/commons-node/process.js +++ b/pkg/commons-node/process.js @@ -1,3 +1,233 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.psTree = exports.getChildrenOfProcess = exports.getOriginalEnvironment = exports.checkOutput = exports.killUnixProcessTree = exports.ProcessExitError = exports.ProcessSystemError = exports.loggedCalls = undefined; + +var _asyncToGenerator = _interopRequireDefault(require('async-to-generator')); + +let _killProcess = (() => { + var _ref = (0, _asyncToGenerator.default)(function* (childProcess, killTree) { + childProcess.wasKilled = true; + if (!killTree) { + childProcess.kill(); + return; + } + if (/^win/.test(process.platform)) { + yield killWindowsProcessTree(childProcess.pid); + } else { + yield killUnixProcessTree(childProcess); + } + }); + + return function _killProcess(_x, _x2) { + return _ref.apply(this, arguments); + }; +})(); + +let killUnixProcessTree = exports.killUnixProcessTree = (() => { + var _ref2 = (0, _asyncToGenerator.default)(function* (childProcess) { + const descendants = yield getDescendantsOfProcess(childProcess.pid); + // Kill the processes, starting with those of greatest depth. + for (const info of descendants.reverse()) { + killPid(info.pid); + } + }); + + return function killUnixProcessTree(_x3) { + return _ref2.apply(this, arguments); + }; +})(); + +/** + * Simple wrapper around asyncExecute that throws if the exitCode is non-zero. + */ +let checkOutput = exports.checkOutput = (() => { + var _ref3 = (0, _asyncToGenerator.default)(function* (command, args, options = {}) { + const result = yield asyncExecute((_nuclideUri || _load_nuclideUri()).default.expandHomeDir(command), args, options); + if (result.exitCode !== 0) { + const reason = result.exitCode != null ? `exitCode: ${result.exitCode}` : `error: ${(0, (_string || _load_string()).maybeToString)(result.errorMessage)}`; + throw new Error(`asyncExecute "${command}" failed with ${reason}, ` + `stderr: ${result.stderr}, stdout: ${result.stdout}.`); + } + return result; + }); + + return function checkOutput(_x4, _x5) { + return _ref3.apply(this, arguments); + }; +})(); + +/** + * Run a command, accumulate the output. Errors are surfaced as stream errors and unsubscribing will + * kill the process. + */ + + +let getOriginalEnvironment = exports.getOriginalEnvironment = (() => { + var _ref4 = (0, _asyncToGenerator.default)(function* () { + yield loadedShellPromise; + + if (cachedOriginalEnvironment != null) { + return cachedOriginalEnvironment; + } + + const { NUCLIDE_ORIGINAL_ENV } = process.env; + if (NUCLIDE_ORIGINAL_ENV != null && NUCLIDE_ORIGINAL_ENV.trim() !== '') { + const envString = new Buffer(NUCLIDE_ORIGINAL_ENV, 'base64').toString(); + cachedOriginalEnvironment = {}; + for (const envVar of envString.split('\0')) { + // envVar should look like A=value_of_A + const equalIndex = envVar.indexOf('='); + if (equalIndex !== -1) { + cachedOriginalEnvironment[envVar.substring(0, equalIndex)] = envVar.substring(equalIndex + 1); + } + } + } else { + cachedOriginalEnvironment = process.env; + } + return cachedOriginalEnvironment; + }); + + return function getOriginalEnvironment() { + return _ref4.apply(this, arguments); + }; +})(); + +// Returns a string suitable for including in displayed error messages. + + +let getChildrenOfProcess = exports.getChildrenOfProcess = (() => { + var _ref5 = (0, _asyncToGenerator.default)(function* (processId) { + const processes = yield psTree(); + + return processes.filter(function (processInfo) { + return processInfo.parentPid === processId; + }); + }); + + return function getChildrenOfProcess(_x6) { + return _ref5.apply(this, arguments); + }; +})(); + +/** + * Get a list of descendants, sorted by increasing depth (including the one with the provided pid). + */ + + +let getDescendantsOfProcess = (() => { + var _ref6 = (0, _asyncToGenerator.default)(function* (pid) { + const processes = yield psTree(); + let rootProcessInfo; + const pidToChildren = new (_collection || _load_collection()).MultiMap(); + processes.forEach(function (info) { + if (info.pid === pid) { + rootProcessInfo = info; + } + pidToChildren.add(info.parentPid, info); + }); + const descendants = rootProcessInfo == null ? [] : [rootProcessInfo]; + // Walk through the array, adding the children of the current element to the end. This + // breadth-first traversal means that the elements will be sorted by depth. + for (let i = 0; i < descendants.length; i++) { + const info = descendants[i]; + const children = pidToChildren.get(info.pid); + descendants.push(...Array.from(children)); + } + return descendants; + }); + + return function getDescendantsOfProcess(_x7) { + return _ref6.apply(this, arguments); + }; +})(); + +let psTree = exports.psTree = (() => { + var _ref7 = (0, _asyncToGenerator.default)(function* () { + let psPromise; + const isWindows = isWindowsPlatform(); + if (isWindows) { + // See also: https://github.com/nodejs/node-v0.x-archive/issues/2318 + psPromise = checkOutput('wmic.exe', ['PROCESS', 'GET', 'ParentProcessId,ProcessId,Name']); + } else { + psPromise = checkOutput('ps', ['-A', '-o', 'ppid,pid,comm']); + } + const { stdout } = yield psPromise; + return parsePsOutput(stdout); + }); + + return function psTree() { + return _ref7.apply(this, arguments); + }; +})(); + +exports.safeSpawn = safeSpawn; +exports.safeFork = safeFork; +exports.createArgsForScriptCommand = createArgsForScriptCommand; +exports.scriptSafeSpawn = scriptSafeSpawn; +exports.scriptSafeSpawnAndObserveOutput = scriptSafeSpawnAndObserveOutput; +exports.killProcess = killProcess; +exports.killPid = killPid; +exports.createProcessStream = createProcessStream; +exports.observeProcessExit = observeProcessExit; +exports.getOutputStream = getOutputStream; +exports.observeProcess = observeProcess; +exports.asyncExecute = asyncExecute; +exports.runCommand = runCommand; +exports.loadedShellEnvironment = loadedShellEnvironment; +exports.exitEventToMessage = exitEventToMessage; +exports.parsePsOutput = parsePsOutput; + +var _child_process = _interopRequireDefault(require('child_process')); + +var _collection; + +function _load_collection() { + return _collection = require('./collection'); +} + +var _nuclideUri; + +function _load_nuclideUri() { + return _nuclideUri = _interopRequireDefault(require('./nuclideUri')); +} + +var _observable; + +function _load_observable() { + return _observable = require('./observable'); +} + +var _stream; + +function _load_stream() { + return _stream = require('./stream'); +} + +var _string; + +function _load_string() { + return _string = require('./string'); +} + +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js'); + +var _shellQuote; + +function _load_shellQuote() { + return _shellQuote = require('shell-quote'); +} + +var _performanceNow; + +function _load_performanceNow() { + return _performanceNow = _interopRequireDefault(require('./performanceNow')); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +// Node crashes if we allow buffers that are too large. /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,73 +235,31 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * */ -import type {ProcessExitMessage, ProcessMessage, ProcessInfo} from './process-rpc-types'; - -import child_process from 'child_process'; -import {MultiMap} from './collection'; -import nuclideUri from './nuclideUri'; -import {splitStream, takeWhileInclusive} from './observable'; -import {observeStream} from './stream'; -import {maybeToString} from './string'; -import {Observable} from 'rxjs'; -import invariant from 'assert'; -import {quote} from 'shell-quote'; -import performanceNow from './performanceNow'; - -// Node crashes if we allow buffers that are too large. const DEFAULT_MAX_BUFFER = 100 * 1024 * 1024; const MAX_LOGGED_CALLS = 100; const PREVERVED_HISTORY_CALLS = 50; -export const loggedCalls = []; +const loggedCalls = exports.loggedCalls = []; function logCall(duration, command, args) { // Trim the history once in a while, to avoid doing expensive array // manipulation all the time after we reached the end of the history if (loggedCalls.length > MAX_LOGGED_CALLS) { - loggedCalls.splice( - 0, - loggedCalls.length - PREVERVED_HISTORY_CALLS, - {time: new Date(), duration: 0, command: '... history stripped ...'}, - ); + loggedCalls.splice(0, loggedCalls.length - PREVERVED_HISTORY_CALLS, { time: new Date(), duration: 0, command: '... history stripped ...' }); } loggedCalls.push({ duration, command: [command, ...args].join(' '), - time: new Date(), + time: new Date() }); } -export type AsyncExecuteReturn = { - // If the process fails to even start up, exitCode will not be set - // and errorCode / errorMessage will contain the actual error message. - // Otherwise, exitCode will always be defined. - errorMessage?: string, - errorCode?: string, - exitCode?: number, - stderr: string, - stdout: string, -}; - -type ProcessSystemErrorOptions = { - command: string, - args: Array, - options: Object, - code: string, - originalError: Error, -}; - -export class ProcessSystemError extends Error { - command: string; - args: Array; - options: Object; - code: string; - originalError: Error; - - constructor(opts: ProcessSystemErrorOptions) { +class ProcessSystemError extends Error { + + constructor(opts) { super(`"${opts.command}" failed with code ${opts.code}`); this.name = 'ProcessSystemError'; this.command = opts.command; @@ -82,28 +270,11 @@ export class ProcessSystemError extends Error { } } -type ProcessExitErrorOptions = { - command: string, - args: Array, - options: Object, - exitMessage: ProcessExitMessage, - stdout: string, - stderr: string, -}; - -export class ProcessExitError extends Error { - command: string; - args: Array; - options: Object; - code: ?number; - exitMessage: ProcessExitMessage; - stdout: string; - stderr: string; - - constructor(opts: ProcessExitErrorOptions) { - super( - `"${opts.command}" failed with ${exitEventToMessage(opts.exitMessage)}\n\n${opts.stderr}`, - ); +exports.ProcessSystemError = ProcessSystemError; +class ProcessExitError extends Error { + + constructor(opts) { + super(`"${opts.command}" failed with ${exitEventToMessage(opts.exitMessage)}\n\n${opts.stderr}`); this.name = 'ProcessExitError'; this.command = opts.command; this.args = opts.args; @@ -115,13 +286,8 @@ export class ProcessExitError extends Error { } } -export type ProcessError = ProcessSystemError | ProcessExitError; +exports.ProcessExitError = ProcessExitError; -export type AsyncExecuteOptions = child_process$execFileOpts & { - // The contents to write to stdin. - stdin?: ?string, - dontLogInNuclide?: ?boolean, -}; const STREAM_NAMES = ['stdin', 'stdout', 'stderr']; @@ -137,7 +303,7 @@ function log(...args) { console.log(...args); } -function monitorStreamErrors(process: child_process$ChildProcess, command, args, options): void { +function monitorStreamErrors(process, command, args, options) { STREAM_NAMES.forEach(streamName => { // $FlowIssue const stream = process[streamName]; @@ -147,14 +313,7 @@ function monitorStreamErrors(process: child_process$ChildProcess, command, args, stream.on('error', error => { // This can happen without the full execution of the command to fail, // but we want to learn about it. - logError( - `stream error on stream ${streamName} with command:`, - command, - args, - options, - 'error:', - error, - ); + logError(`stream error on stream ${streamName} with command:`, command, args, options, 'error:', error); }); }); } @@ -164,46 +323,29 @@ function monitorStreamErrors(process: child_process$ChildProcess, command, args, * crashing the process. This is much lower-level than asyncExecute. Unless * you have a specific reason you should use asyncExecute instead. */ -export function safeSpawn( - command: string, - args?: Array = [], - options?: child_process$spawnOpts = {}, -): child_process$ChildProcess { +function safeSpawn(command, args = [], options = {}) { return _makeChildProcess('spawn', command, args, options); } -export function safeFork( - command: string, - args?: Array = [], - options?: child_process$forkOpts = {}, -): child_process$ChildProcess { +function safeFork(command, args = [], options = {}) { return _makeChildProcess('fork', command, args, options); } /** * Helper type/function to create child_process by spawning/forking the process. */ -type ChildProcessOpts = child_process$spawnOpts | child_process$forkOpts; - -function _makeChildProcess( - type: 'spawn' | 'fork' = 'spawn', - command: string, - args?: Array = [], - options?: ChildProcessOpts = {}, -): child_process$ChildProcess { - const now = performanceNow(); - const child = child_process[type]( - nuclideUri.expandHomeDir(command), - args, - prepareProcessOptions(options), - ); + + +function _makeChildProcess(type = 'spawn', command, args = [], options = {}) { + const now = (0, (_performanceNow || _load_performanceNow()).default)(); + const child = _child_process.default[type]((_nuclideUri || _load_nuclideUri()).default.expandHomeDir(command), args, prepareProcessOptions(options)); monitorStreamErrors(child, command, args, options); child.on('error', error => { logError('error with command:', command, args, options, 'error:', error); }); if (!options || !options.dontLogInNuclide) { child.on('close', () => { - logCall(Math.round(performanceNow() - now), command, args); + logCall(Math.round((0, (_performanceNow || _load_performanceNow()).default)() - now), command, args); }); } writeToStdin(child, options); @@ -215,17 +357,14 @@ function _makeChildProcess( * that you should call it with `spawn('script', newArgs)` to run the original command/args pair * under `script`. */ -export function createArgsForScriptCommand( - command: string, - args?: Array = [], -): Array { +function createArgsForScriptCommand(command, args = []) { if (process.platform === 'darwin') { // On OS X, script takes the program to run and its arguments as varargs at the end. return ['-q', '/dev/null', command].concat(args); } else { // On Linux, script takes the command to run as the -c parameter. const allArgs = [command].concat(args); - return ['-q', '/dev/null', '-c', quote(allArgs)]; + return ['-q', '/dev/null', '-c', (0, (_shellQuote || _load_shellQuote()).quote)(allArgs)]; } } @@ -233,11 +372,7 @@ export function createArgsForScriptCommand( * Basically like safeSpawn, but runs the command with the `script` command. * `script` ensures terminal-like environment and commands we run give colored output. */ -export function scriptSafeSpawn( - command: string, - args?: Array = [], - options?: Object = {}, -): child_process$ChildProcess { +function scriptSafeSpawn(command, args = [], options = {}) { const newArgs = createArgsForScriptCommand(command, args); return safeSpawn('script', newArgs, options); } @@ -246,26 +381,21 @@ export function scriptSafeSpawn( * Wraps scriptSafeSpawn with an Observable that lets you listen to the stdout and * stderr of the spawned process. */ -export function scriptSafeSpawnAndObserveOutput( - command: string, - args?: Array = [], - options?: Object = {}, - killTreeOnComplete?: boolean = false, -): Observable<{stderr?: string, stdout?: string}> { - return Observable.create((observer: rxjs$Observer) => { +function scriptSafeSpawnAndObserveOutput(command, args = [], options = {}, killTreeOnComplete = false) { + return _rxjsBundlesRxMinJs.Observable.create(observer => { let childProcess = scriptSafeSpawn(command, args, options); childProcess.stdout.on('data', data => { - observer.next({stdout: data.toString()}); + observer.next({ stdout: data.toString() }); }); let stderr = ''; childProcess.stderr.on('data', data => { stderr += data; - observer.next({stderr: data.toString()}); + observer.next({ stderr: data.toString() }); }); - childProcess.on('exit', (exitCode: number) => { + childProcess.on('exit', exitCode => { if (exitCode !== 0) { observer.error(stderr); } else { @@ -294,12 +424,8 @@ export function scriptSafeSpawnAndObserveOutput( * * IMPORTANT: The exit event does NOT mean that all stdout and stderr events have been received. */ -function _createProcessStream( - createProcess: () => child_process$ChildProcess, - throwOnError: boolean, - killTreeOnComplete: boolean, -): Observable { - return Observable.defer(() => { +function _createProcessStream(createProcess, throwOnError, killTreeOnComplete) { + return _rxjsBundlesRxMinJs.Observable.defer(() => { const process = createProcess(); let finished = false; @@ -310,64 +436,43 @@ function _createProcessStream( // possible, you need to make sure that the process is passed here immediately after it's // created (i.e. before an ENOENT error event would be dispatched). Don't refactor your code to // avoid this function; you'll have the same bug, you just won't be notified! XD - invariant( - process.exitCode == null && !process.killed, - 'Process already exited. (This indicates a race condition in Nuclide.)', - ); - const errors = Observable.fromEvent(process, 'error'); + if (!(process.exitCode == null && !process.killed)) { + throw new Error('Process already exited. (This indicates a race condition in Nuclide.)'); + } + + const errors = _rxjsBundlesRxMinJs.Observable.fromEvent(process, 'error'); const exit = observeProcessExitMessage(process); - return Observable.of(process) - // Don't complete until we say so! - .merge(Observable.never()) - // Get the errors. - .takeUntil(throwOnError ? errors.flatMap(Observable.throw) : errors) - .takeUntil(exit) - .do({ - error: () => { finished = true; }, - complete: () => { finished = true; }, - }) - .finally(() => { - if (!process.wasKilled && !finished) { - killProcess(process, killTreeOnComplete); - } - }); + return _rxjsBundlesRxMinJs.Observable.of(process) + // Don't complete until we say so! + .merge(_rxjsBundlesRxMinJs.Observable.never()) + // Get the errors. + .takeUntil(throwOnError ? errors.flatMap(_rxjsBundlesRxMinJs.Observable.throw) : errors).takeUntil(exit).do({ + error: () => { + finished = true; + }, + complete: () => { + finished = true; + } + }).finally(() => { + if (!process.wasKilled && !finished) { + killProcess(process, killTreeOnComplete); + } + }); }); } -export function killProcess( - childProcess: child_process$ChildProcess, - killTree: boolean, -): void { +function killProcess(childProcess, killTree) { log(`Ending process stream. Killing process ${childProcess.pid}`); - _killProcess(childProcess, killTree).then( - () => {}, - error => { - logError(`Killing process ${childProcess.pid} failed`, error); - }, - ); -} - -async function _killProcess( - childProcess: child_process$ChildProcess & {wasKilled?: boolean}, - killTree: boolean, -): Promise { - childProcess.wasKilled = true; - if (!killTree) { - childProcess.kill(); - return; - } - if (/^win/.test(process.platform)) { - await killWindowsProcessTree(childProcess.pid); - } else { - await killUnixProcessTree(childProcess); - } + _killProcess(childProcess, killTree).then(() => {}, error => { + logError(`Killing process ${childProcess.pid} failed`, error); + }); } -function killWindowsProcessTree(pid: number): Promise { +function killWindowsProcessTree(pid) { return new Promise((resolve, reject) => { - child_process.exec(`taskkill /pid ${pid} /T /F`, error => { + _child_process.default.exec(`taskkill /pid ${pid} /T /F`, error => { if (error == null) { reject(error); } else { @@ -377,7 +482,7 @@ function killWindowsProcessTree(pid: number): Promise { }); } -export function killPid(pid: number): void { +function killPid(pid) { try { process.kill(pid); } catch (err) { @@ -387,85 +492,49 @@ export function killPid(pid: number): void { } } - -export async function killUnixProcessTree(childProcess: child_process$ChildProcess): Promise { - const descendants = await getDescendantsOfProcess(childProcess.pid); - // Kill the processes, starting with those of greatest depth. - for (const info of descendants.reverse()) { - killPid(info.pid); - } -} - -export function createProcessStream( - createProcess: () => child_process$ChildProcess, - killTreeOnComplete?: boolean = false, -): Observable { +function createProcessStream(createProcess, killTreeOnComplete = false) { return _createProcessStream(createProcess, true, killTreeOnComplete); } -function observeProcessExitMessage( - process: child_process$ChildProcess, -): Observable { - return Observable.fromEvent( - process, - 'exit', - (exitCode: ?number, signal: ?string) => ({kind: 'exit', exitCode, signal})) - // An exit signal from SIGUSR1 doesn't actually exit the process, so skip that. - .filter(message => message.signal !== 'SIGUSR1') - .take(1); +function observeProcessExitMessage(process) { + return _rxjsBundlesRxMinJs.Observable.fromEvent(process, 'exit', (exitCode, signal) => ({ kind: 'exit', exitCode, signal })) + // An exit signal from SIGUSR1 doesn't actually exit the process, so skip that. + .filter(message => message.signal !== 'SIGUSR1').take(1); } /** * Observe the stdout, stderr and exit code of a process. * stdout and stderr are split by newlines. */ -export function observeProcessExit( - createProcess: () => child_process$ChildProcess, - killTreeOnComplete?: boolean = false, -): Observable { - return _createProcessStream(createProcess, false, killTreeOnComplete) - .flatMap(observeProcessExitMessage); -} - -export function getOutputStream( - process: child_process$ChildProcess, - killTreeOnComplete?: boolean = false, -): Observable { - return Observable.defer(() => { +function observeProcessExit(createProcess, killTreeOnComplete = false) { + return _createProcessStream(createProcess, false, killTreeOnComplete).flatMap(observeProcessExitMessage); +} + +function getOutputStream(process, killTreeOnComplete = false) { + return _rxjsBundlesRxMinJs.Observable.defer(() => { // We need to start listening for the exit event immediately, but defer emitting it until the // (buffered) output streams end. const exit = observeProcessExit(() => process, killTreeOnComplete).publishReplay(); const exitSub = exit.connect(); - const error = Observable.fromEvent(process, 'error') - .map(errorObj => ({kind: 'error', error: errorObj})); + const error = _rxjsBundlesRxMinJs.Observable.fromEvent(process, 'error').map(errorObj => ({ kind: 'error', error: errorObj })); // It's possible for stdout and stderr to remain open (even indefinitely) after the exit event. // This utility, however, treats the exit event as stream-ending, which helps us to avoid easy // bugs. We give a short (100ms) timeout for the stdout and stderr streams to close. const close = exit.delay(100); - const stdout = splitStream(observeStream(process.stdout).takeUntil(close)) - .map(data => ({kind: 'stdout', data})); - const stderr = splitStream(observeStream(process.stderr).takeUntil(close)) - .map(data => ({kind: 'stderr', data})); - - return takeWhileInclusive( - Observable.merge( - Observable.merge(stdout, stderr).concat(exit), - error, - ), - event => event.kind !== 'error' && event.kind !== 'exit', - ) - .finally(() => { exitSub.unsubscribe(); }); + const stdout = (0, (_observable || _load_observable()).splitStream)((0, (_stream || _load_stream()).observeStream)(process.stdout).takeUntil(close)).map(data => ({ kind: 'stdout', data })); + const stderr = (0, (_observable || _load_observable()).splitStream)((0, (_stream || _load_stream()).observeStream)(process.stderr).takeUntil(close)).map(data => ({ kind: 'stderr', data })); + + return (0, (_observable || _load_observable()).takeWhileInclusive)(_rxjsBundlesRxMinJs.Observable.merge(_rxjsBundlesRxMinJs.Observable.merge(stdout, stderr).concat(exit), error), event => event.kind !== 'error' && event.kind !== 'exit').finally(() => { + exitSub.unsubscribe(); + }); }); } /** * Observe the stdout, stderr and exit code of a process. */ -export function observeProcess( - createProcess: () => child_process$ChildProcess, - killTreeOnComplete?: boolean = false, -): Observable { +function observeProcess(createProcess, killTreeOnComplete = false) { return _createProcessStream(createProcess, false, killTreeOnComplete).flatMap(getOutputStream); } @@ -477,33 +546,23 @@ try { FB_INCLUDE_PATHS = []; } -let DEFAULT_PATH_INCLUDE = [ - ...FB_INCLUDE_PATHS, - '/usr/local/bin', -]; +let DEFAULT_PATH_INCLUDE = [...FB_INCLUDE_PATHS, '/usr/local/bin']; -function prepareProcessOptions( - options: Object, -): Object { - return { - ...options, - env: preparePathEnvironment(options.env), - }; +function prepareProcessOptions(options) { + return Object.assign({}, options, { + env: preparePathEnvironment(options.env) + }); } -function preparePathEnvironment(env: ?Object): Object { - const originalEnv = { - ...process.env, - ...env, - }; +function preparePathEnvironment(env) { + const originalEnv = Object.assign({}, process.env, env); if (isWindowsPlatform()) { return originalEnv; } - const existingPath: string = originalEnv.PATH || ''; - return { - ...originalEnv, - PATH: nuclideUri.joinPathList([existingPath, ...DEFAULT_PATH_INCLUDE]), - }; + const existingPath = originalEnv.PATH || ''; + return Object.assign({}, originalEnv, { + PATH: (_nuclideUri || _load_nuclideUri()).default.joinPathList([existingPath, ...DEFAULT_PATH_INCLUDE]) + }); } /** @@ -515,57 +574,45 @@ function preparePathEnvironment(env: ?Object): Object { * Supports the options listed here: http://nodejs.org/api/child_process.html * in addition to the custom options listed in AsyncExecuteOptions. */ -export function asyncExecute( - command: string, - args: Array, - options?: AsyncExecuteOptions = {}, -): Promise { - const now = performanceNow(); +function asyncExecute(command, args, options = {}) { + const now = (0, (_performanceNow || _load_performanceNow()).default)(); return new Promise((resolve, reject) => { - const process = child_process.execFile( - nuclideUri.expandHomeDir(command), - args, - prepareProcessOptions({ - maxBuffer: DEFAULT_MAX_BUFFER, - ...options, - }), - // Node embeds various properties like code/errno in the Error object. - (err: any /* Error */, stdoutBuf, stderrBuf) => { - if (!options || !options.dontLogInNuclide) { - logCall(Math.round(performanceNow() - now), command, args); - } - const stdout = stdoutBuf.toString('utf8'); - const stderr = stderrBuf.toString('utf8'); - if (err == null) { - resolve({ - stdout, - stderr, - exitCode: 0, - }); - } else if (Number.isInteger(err.code)) { - resolve({ - stdout, - stderr, - exitCode: err.code, - }); - } else { - resolve({ - stdout, - stderr, - errorCode: err.errno || 'EUNKNOWN', - errorMessage: err.message, - }); - } - }, - ); + const process = _child_process.default.execFile((_nuclideUri || _load_nuclideUri()).default.expandHomeDir(command), args, prepareProcessOptions(Object.assign({ + maxBuffer: DEFAULT_MAX_BUFFER + }, options)), + // Node embeds various properties like code/errno in the Error object. + (err, /* Error */stdoutBuf, stderrBuf) => { + if (!options || !options.dontLogInNuclide) { + logCall(Math.round((0, (_performanceNow || _load_performanceNow()).default)() - now), command, args); + } + const stdout = stdoutBuf.toString('utf8'); + const stderr = stderrBuf.toString('utf8'); + if (err == null) { + resolve({ + stdout, + stderr, + exitCode: 0 + }); + } else if (Number.isInteger(err.code)) { + resolve({ + stdout, + stderr, + exitCode: err.code + }); + } else { + resolve({ + stdout, + stderr, + errorCode: err.errno || 'EUNKNOWN', + errorMessage: err.message + }); + } + }); writeToStdin(process, options); }); } -function writeToStdin( - childProcess: child_process$ChildProcess, - options: Object, -): void { +function writeToStdin(childProcess, options) { if (typeof options.stdin === 'string' && childProcess.stdin != null) { // Note that the Node docs have this scary warning about stdin.end() on // http://nodejs.org/api/child_process.html#child_process_child_stdin: @@ -577,86 +624,49 @@ function writeToStdin( childProcess.stdin.write(options.stdin); childProcess.stdin.end(); } -} - -/** - * Simple wrapper around asyncExecute that throws if the exitCode is non-zero. - */ -export async function checkOutput( - command: string, - args: Array, - options?: AsyncExecuteOptions = {}, -): Promise { - const result = await asyncExecute(nuclideUri.expandHomeDir(command), args, options); - if (result.exitCode !== 0) { - const reason = result.exitCode != null ? `exitCode: ${result.exitCode}` : - `error: ${maybeToString(result.errorMessage)}`; - throw new Error( - `asyncExecute "${command}" failed with ${reason}, ` + - `stderr: ${result.stderr}, stdout: ${result.stdout}.`, - ); - } - return result; -} - -/** - * Run a command, accumulate the output. Errors are surfaced as stream errors and unsubscribing will - * kill the process. - */ -export function runCommand( - command: string, - args?: Array = [], - options?: Object = {}, - killTreeOnComplete?: boolean = false, -): Observable { - return observeProcess(() => safeSpawn(command, args, options), killTreeOnComplete) - .reduce( - (acc, event) => { - switch (event.kind) { - case 'stdout': - acc.stdout += event.data; - break; - case 'stderr': - acc.stderr += event.data; - break; - case 'error': - acc.error = event.error; - break; - case 'exit': - acc.exitMessage = event; - break; - } - return acc; - }, - { - error: ((null: any): Object), - stdout: '', - stderr: '', - exitMessage: ((null: any): ?ProcessExitMessage), - }, - ) - .map(acc => { - if (acc.error != null) { - throw new ProcessSystemError({ - command, - args, - options, - code: acc.error.code, // Alias of errno - originalError: acc.error, // Just in case. - }); - } - if (acc.exitMessage != null && acc.exitMessage.exitCode !== 0) { - throw new ProcessExitError({ - command, - args, - options, - exitMessage: acc.exitMessage, - stdout: acc.stdout, - stderr: acc.stderr, - }); - } - return acc.stdout; - }); +}function runCommand(command, args = [], options = {}, killTreeOnComplete = false) { + return observeProcess(() => safeSpawn(command, args, options), killTreeOnComplete).reduce((acc, event) => { + switch (event.kind) { + case 'stdout': + acc.stdout += event.data; + break; + case 'stderr': + acc.stderr += event.data; + break; + case 'error': + acc.error = event.error; + break; + case 'exit': + acc.exitMessage = event; + break; + } + return acc; + }, { + error: null, + stdout: '', + stderr: '', + exitMessage: null + }).map(acc => { + if (acc.error != null) { + throw new ProcessSystemError({ + command, + args, + options, + code: acc.error.code, // Alias of errno + originalError: acc.error }); + } + if (acc.exitMessage != null && acc.exitMessage.exitCode !== 0) { + throw new ProcessExitError({ + command, + args, + options, + exitMessage: acc.exitMessage, + stdout: acc.stdout, + stderr: acc.stderr + }); + } + return acc.stdout; + }); } // If provided, read the original environment from NUCLIDE_ORIGINAL_ENV. @@ -672,106 +682,37 @@ const loadedShellPromise = new Promise(resolve => { cachedOriginalEnvironment = null; }); -invariant(loadedShellResolve); +if (!loadedShellResolve) { + throw new Error('Invariant violation: "loadedShellResolve"'); +} + if (typeof atom === 'undefined' || atom.inSpecMode()) { // This doesn't apply server-side or in tests, so just immediately resolve. loadedShellResolve(); } -export function loadedShellEnvironment(): void { +function loadedShellEnvironment() { loadedShellResolve(); } -export async function getOriginalEnvironment(): Promise { - await loadedShellPromise; - - if (cachedOriginalEnvironment != null) { - return cachedOriginalEnvironment; - } - - const {NUCLIDE_ORIGINAL_ENV} = process.env; - if (NUCLIDE_ORIGINAL_ENV != null && NUCLIDE_ORIGINAL_ENV.trim() !== '') { - const envString = new Buffer(NUCLIDE_ORIGINAL_ENV, 'base64').toString(); - cachedOriginalEnvironment = {}; - for (const envVar of envString.split('\0')) { - // envVar should look like A=value_of_A - const equalIndex = envVar.indexOf('='); - if (equalIndex !== -1) { - cachedOriginalEnvironment[envVar.substring(0, equalIndex)] = - envVar.substring(equalIndex + 1); - } - } - } else { - cachedOriginalEnvironment = process.env; - } - return cachedOriginalEnvironment; -} - -// Returns a string suitable for including in displayed error messages. -export function exitEventToMessage(event: ProcessExitMessage): string { +function exitEventToMessage(event) { if (event.exitCode != null) { return `exit code ${event.exitCode}`; } else { - invariant(event.signal != null); - return `signal ${event.signal}`; - } -} - -export async function getChildrenOfProcess( - processId: number, -): Promise> { - const processes = await psTree(); - - return processes.filter(processInfo => - processInfo.parentPid === processId); -} - -/** - * Get a list of descendants, sorted by increasing depth (including the one with the provided pid). - */ -async function getDescendantsOfProcess(pid: number): Promise> { - const processes = await psTree(); - let rootProcessInfo; - const pidToChildren = new MultiMap(); - processes.forEach(info => { - if (info.pid === pid) { - rootProcessInfo = info; + if (!(event.signal != null)) { + throw new Error('Invariant violation: "event.signal != null"'); } - pidToChildren.add(info.parentPid, info); - }); - const descendants = rootProcessInfo == null ? [] : [rootProcessInfo]; - // Walk through the array, adding the children of the current element to the end. This - // breadth-first traversal means that the elements will be sorted by depth. - for (let i = 0; i < descendants.length; i++) { - const info = descendants[i]; - const children = pidToChildren.get(info.pid); - descendants.push(...Array.from(children)); - } - return descendants; -} -function isWindowsPlatform(): boolean { - return /^win/.test(process.platform); + return `signal ${event.signal}`; + } } -export async function psTree(): Promise> { - let psPromise; - const isWindows = isWindowsPlatform(); - if (isWindows) { - // See also: https://github.com/nodejs/node-v0.x-archive/issues/2318 - psPromise = checkOutput('wmic.exe', - ['PROCESS', 'GET', 'ParentProcessId,ProcessId,Name']); - } else { - psPromise = checkOutput('ps', - ['-A', '-o', 'ppid,pid,comm']); - } - const {stdout} = await psPromise; - return parsePsOutput(stdout); +function isWindowsPlatform() { + return (/^win/.test(process.platform) + ); } -export function parsePsOutput( - psOutput: string, -): Array { +function parsePsOutput(psOutput) { // Remove the first header line. const lines = psOutput.split(/\n|\r\n/).slice(1); @@ -783,7 +724,7 @@ export function parsePsOutput( return { command, parentPid: parseInt(parentPid, 10), - pid: parseInt(pid, 10), + pid: parseInt(pid, 10) }; }); -} +} \ No newline at end of file diff --git a/pkg/commons-node/promise-executors.js b/pkg/commons-node/promise-executors.js index 68f045b4e9..7ec4664273 100644 --- a/pkg/commons-node/promise-executors.js +++ b/pkg/commons-node/promise-executors.js @@ -1,17 +1,19 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the license found in the LICENSE file in - * the root directory of this source tree. - * - * @flow - */ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.PromiseQueue = exports.PromisePool = undefined; -import Dequeue from 'dequeue'; -import EventEmitter from 'events'; +var _dequeue; + +function _load_dequeue() { + return _dequeue = _interopRequireDefault(require('dequeue')); +} -type Executor = () => Promise; +var _events = _interopRequireDefault(require('events')); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /** * A pool that executes Promise executors in parallel given the poolSize, in order. @@ -21,16 +23,21 @@ type Executor = () => Promise; * a sequence of async operations that need to be run in parallel and you also want * control the number of concurrent executions. */ -export class PromisePool { - _fifo: Dequeue; - _emitter: EventEmitter; - _numPromisesRunning: number; - _poolSize: number; - _nextRequestId: number; - - constructor(poolSize: number) { - this._fifo = new Dequeue(); - this._emitter = new EventEmitter(); +/** + * Copyright (c) 2015-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the license found in the LICENSE file in + * the root directory of this source tree. + * + * + */ + +class PromisePool { + + constructor(poolSize) { + this._fifo = new (_dequeue || _load_dequeue()).default(); + this._emitter = new _events.default(); this._numPromisesRunning = 0; this._poolSize = poolSize; this._nextRequestId = 1; @@ -42,12 +49,12 @@ export class PromisePool { * @return A Promise that will be resolved/rejected in response to the * execution of the executor. */ - submit(executor: Executor): Promise { + submit(executor) { const id = this._getNextRequestId(); - this._fifo.push({id, executor}); + this._fifo.push({ id, executor }); const promise = new Promise((resolve, reject) => { this._emitter.once(id, result => { - const {isSuccess, value} = result; + const { isSuccess, value } = result; (isSuccess ? resolve : reject)(value); }); }); @@ -64,34 +71,34 @@ export class PromisePool { return; } - const {id, executor} = this._fifo.shift(); + const { id, executor } = this._fifo.shift(); this._numPromisesRunning++; executor().then(result => { - this._emitter.emit(id, {isSuccess: true, value: result}); + this._emitter.emit(id, { isSuccess: true, value: result }); this._numPromisesRunning--; this._run(); }, error => { - this._emitter.emit(id, {isSuccess: false, value: error}); + this._emitter.emit(id, { isSuccess: false, value: error }); this._numPromisesRunning--; this._run(); }); } - _getNextRequestId(): string { + _getNextRequestId() { return (this._nextRequestId++).toString(16); } } -/** - * FIFO queue that executes Promise executors one at a time, in order. - * - * The executor function passed to the constructor of a Promise is evaluated - * immediately. This may not always be desirable. Use a PromiseQueue if you have - * a sequence of async operations that need to use a shared resource serially. - */ -export class PromiseQueue { - _promisePool: PromisePool; +exports.PromisePool = PromisePool; /** + * FIFO queue that executes Promise executors one at a time, in order. + * + * The executor function passed to the constructor of a Promise is evaluated + * immediately. This may not always be desirable. Use a PromiseQueue if you have + * a sequence of async operations that need to use a shared resource serially. + */ + +class PromiseQueue { constructor() { this._promisePool = new PromisePool(1); @@ -103,7 +110,8 @@ export class PromiseQueue { * @return A Promise that will be resolved/rejected in response to the * execution of the executor. */ - submit(executor: Executor): Promise { + submit(executor) { return this._promisePool.submit(executor); } } +exports.PromiseQueue = PromiseQueue; \ No newline at end of file diff --git a/pkg/commons-node/promise.js b/pkg/commons-node/promise.js index 45a3e05016..9358f0c090 100644 --- a/pkg/commons-node/promise.js +++ b/pkg/commons-node/promise.js @@ -1,21 +1,252 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.asyncSome = exports.asyncObjFilter = exports.asyncFilter = exports.Deferred = exports.retryLimit = exports.triggerAfterWait = exports.RequestSerializer = undefined; + +var _asyncToGenerator = _interopRequireDefault(require('async-to-generator')); + /** - * Copyright (c) 2015-present, Facebook, Inc. - * All rights reserved. + * Executes a provided callback only if a promise takes longer than + * `milliSeconds` milliseconds to resolve. * - * This source code is licensed under the license found in the LICENSE file in - * the root directory of this source tree. + * @param `promise` the promise to wait on. + * @param `milliSeconds` max amount of time that `promise` can take to resolve + * before timeoutFn is fired. + * @param `timeoutFn` the function to execute when a promise takes longer than + * `milliSeconds` ms to resolve. + * @param `cleanupFn` the cleanup function to execute after the promise resolves. + */ +let triggerAfterWait = exports.triggerAfterWait = (() => { + var _ref = (0, _asyncToGenerator.default)(function* (promise, milliSeconds, timeoutFn, cleanupFn) { + const timeout = setTimeout(timeoutFn, milliSeconds); + try { + return yield promise; + } finally { + clearTimeout(timeout); + if (cleanupFn) { + cleanupFn(); + } + } + }); + + return function triggerAfterWait(_x, _x2, _x3, _x4) { + return _ref.apply(this, arguments); + }; +})(); + +/** + * Returns a Promise that resolves to the same value as the given promise, or rejects if it takes + * longer than `milliseconds` milliseconds + */ + + +/** + * Call an async function repeatedly with a maximum number of trials limit, + * until a valid result that's defined by a validation function. + * A failed call can result from an async thrown exception, or invalid result. + * + * @param `retryFunction` the async logic that's wanted to be retried. + * @param `validationFunction` the validation function that decides whether a response is valid. + * @param `maximumTries` the number of times the `retryFunction` can fail to get a valid + * response before the `retryLimit` is terminated reporting an error. + * @param `retryIntervalMs` optional, the number of milliseconds to wait between trials, if wanted. * - * @flow + * If an exception is encountered on the last trial, the exception is thrown. + * If no valid response is found, an exception is thrown. */ +let retryLimit = exports.retryLimit = (() => { + var _ref2 = (0, _asyncToGenerator.default)(function* (retryFunction, validationFunction, maximumTries, retryIntervalMs = 0) { + let result = null; + let tries = 0; + let lastError = null; + while (tries === 0 || tries < maximumTries) { + try { + // eslint-disable-next-line no-await-in-loop + result = yield retryFunction(); + lastError = null; + if (validationFunction(result)) { + return result; + } + } catch (error) { + lastError = error; + result = null; + } -import invariant from 'assert'; + if (++tries < maximumTries && retryIntervalMs !== 0) { + // eslint-disable-next-line no-await-in-loop + yield sleep(retryIntervalMs); + } + } + if (lastError != null) { + throw lastError; + } else if (tries === maximumTries) { + throw new Error('No valid response found!'); + } else { + return result; + } + }); -type RunReturn = { - status: 'success', - result: T, -} | { - status: 'outdated', -}; + return function retryLimit(_x5, _x6, _x7) { + return _ref2.apply(this, arguments); + }; +})(); + +/** + * Limits async function execution parallelism to only one at a time. + * Hence, if a call is already running, it will wait for it to finish, + * then start the next async execution, but if called again while not finished, + * it will return the scheduled execution promise. + * + * Sample Usage: + * ``` + * let i = 1; + * const oneExecAtATime = oneParallelAsyncCall(() => { + * return next Promise((resolve, reject) => { + * setTimeout(200, () => resolve(i++)); + * }); + * }); + * + * const result1Promise = oneExecAtATime(); // Start an async, and resolve to 1 in 200 ms. + * const result2Promise = oneExecAtATime(); // Schedule the next async, and resolve to 2 in 400 ms. + * const result3Promise = oneExecAtATime(); // Reuse scheduled promise and resolve to 2 in 400 ms. + * ``` + */ + + +/** + * `filter` Promise utility that allows filtering an array with an async Promise function. + * It's an alternative to `Array.prototype.filter` that accepts an async function. + * You can optionally configure a limit to set the maximum number of async operations at a time. + * + * Previously, with the `Promise.all` primitive, we can't set the parallelism limit and we have to + * `filter`, so, we replace the old `filter` code: + * var existingFilePaths = []; + * await Promise.all(filePaths.map(async (filePath) => { + * if (await fsPromise.exists(filePath)) { + * existingFilePaths.push(filePath); + * } + * })); + * with limit 5 parallel filesystem operations at a time: + * var existingFilePaths = await asyncFilter(filePaths, fsPromise.exists, 5); + * + * @param array the array of items for `filter`ing. + * @param filterFunction the async `filter` function that returns a Promise that resolves to a + * boolean. + * @param limit the configurable number of parallel async operations. + */ +let asyncFilter = exports.asyncFilter = (() => { + var _ref5 = (0, _asyncToGenerator.default)(function* (array, filterFunction, limit) { + const filteredList = []; + yield asyncLimit(array, limit || array.length, (() => { + var _ref6 = (0, _asyncToGenerator.default)(function* (item) { + if (yield filterFunction(item)) { + filteredList.push(item); + } + }); + + return function (_x12) { + return _ref6.apply(this, arguments); + }; + })()); + return filteredList; + }); + + return function asyncFilter(_x9, _x10, _x11) { + return _ref5.apply(this, arguments); + }; +})(); + +let asyncObjFilter = exports.asyncObjFilter = (() => { + var _ref7 = (0, _asyncToGenerator.default)(function* (obj, filterFunction, limit) { + const keys = Object.keys(obj); + const filteredObj = {}; + yield asyncLimit(keys, limit || keys.length, (() => { + var _ref8 = (0, _asyncToGenerator.default)(function* (key) { + const item = obj[key]; + if (yield filterFunction(item, key)) { + filteredObj[key] = item; + } + }); + + return function (_x16) { + return _ref8.apply(this, arguments); + }; + })()); + return filteredObj; + }); + + return function asyncObjFilter(_x13, _x14, _x15) { + return _ref7.apply(this, arguments); + }; +})(); + +/** + * `some` Promise utility that allows `some` an array with an async Promise some function. + * It's an alternative to `Array.prototype.some` that accepts an async some function. + * You can optionally configure a limit to set the maximum number of async operations at a time. + * + * Previously, with the Promise.all primitive, we can't set the parallelism limit and we have to + * `some`, so, we replace the old `some` code: + * var someFileExist = false; + * await Promise.all(filePaths.map(async (filePath) => { + * if (await fsPromise.exists(filePath)) { + * someFileExist = true; + * } + * })); + * with limit 5 parallel filesystem operations at a time: + * var someFileExist = await asyncSome(filePaths, fsPromise.exists, 5); + * + * @param array the array of items for `some`ing. + * @param someFunction the async `some` function that returns a Promise that resolves to a + * boolean. + * @param limit the configurable number of parallel async operations. + */ + + +let asyncSome = exports.asyncSome = (() => { + var _ref9 = (0, _asyncToGenerator.default)(function* (array, someFunction, limit) { + let resolved = false; + yield asyncLimit(array, limit || array.length, (() => { + var _ref10 = (0, _asyncToGenerator.default)(function* (item) { + if (resolved) { + // We don't need to call the someFunction anymore or wait any longer. + return; + } + if (yield someFunction(item)) { + resolved = true; + } + }); + + return function (_x20) { + return _ref10.apply(this, arguments); + }; + })()); + return resolved; + }); + + return function asyncSome(_x17, _x18, _x19) { + return _ref9.apply(this, arguments); + }; +})(); + +/** + * Check if an object is Promise by testing if it has a `then` function property. + */ + + +exports.sleep = sleep; +exports.nextTick = nextTick; +exports.timeoutPromise = timeoutPromise; +exports.serializeAsyncCall = serializeAsyncCall; +exports.asyncFind = asyncFind; +exports.denodeify = denodeify; +exports.asyncLimit = asyncLimit; +exports.isPromise = isPromise; +exports.lastly = lastly; + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /** * Allows a caller to ensure that the results it receives from consecutive @@ -42,11 +273,17 @@ type RunReturn = { * receive a 'success' status. If promise1 later resolved, the first callsite * would receive an 'outdated' status. */ -export class RequestSerializer { - _lastDispatchedOp: number; - _lastFinishedOp: number; - _latestPromise: Promise; - _waitResolve: Function; +/** + * Copyright (c) 2015-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the license found in the LICENSE file in + * the root directory of this source tree. + * + * + */ + +class RequestSerializer { constructor() { this._lastDispatchedOp = 0; @@ -56,107 +293,79 @@ export class RequestSerializer { }); } - async run(promise: Promise): Promise> { - const thisOp = this._lastDispatchedOp + 1; - this._lastDispatchedOp = thisOp; - this._latestPromise = promise; - this._waitResolve(); - const result = await promise; - if (this._lastFinishedOp < thisOp) { - this._lastFinishedOp = thisOp; - return { - status: 'success', - result, - }; - } else { - return { - status: 'outdated', - }; - } + run(promise) { + var _this = this; + + return (0, _asyncToGenerator.default)(function* () { + const thisOp = _this._lastDispatchedOp + 1; + _this._lastDispatchedOp = thisOp; + _this._latestPromise = promise; + _this._waitResolve(); + const result = yield promise; + if (_this._lastFinishedOp < thisOp) { + _this._lastFinishedOp = thisOp; + return { + status: 'success', + result + }; + } else { + return { + status: 'outdated' + }; + } + })(); } /** * Returns a Promise that resolves to the last result of `run`, * as soon as there are no more outstanding `run` calls. */ - async waitForLatestResult(): Promise { - let lastPromise = null; - let result: any = null; - while (lastPromise !== this._latestPromise) { - lastPromise = this._latestPromise; - // Wait for the current last know promise to resolve, or a next run have started. - // eslint-disable-next-line no-await-in-loop - result = await new Promise((resolve, reject) => { - this._waitResolve = resolve; - this._latestPromise.then(resolve); - }); - } - return (result: T); + waitForLatestResult() { + var _this2 = this; + + return (0, _asyncToGenerator.default)(function* () { + let lastPromise = null; + let result = null; + while (lastPromise !== _this2._latestPromise) { + lastPromise = _this2._latestPromise; + // Wait for the current last know promise to resolve, or a next run have started. + // eslint-disable-next-line no-await-in-loop + result = yield new Promise(function (resolve, reject) { + _this2._waitResolve = resolve; + _this2._latestPromise.then(resolve); + }); + } + return result; + })(); } - isRunInProgress(): boolean { + isRunInProgress() { return this._lastDispatchedOp > this._lastFinishedOp; } } +exports.RequestSerializer = RequestSerializer; /* + * Returns a promise that will resolve after `milliSeconds` milli seconds. + * this can be used to pause execution asynchronously. + * e.g. await sleep(1000), pauses the async flow execution for 1 second. + */ -/* - * Returns a promise that will resolve after `milliSeconds` milli seconds. - * this can be used to pause execution asynchronously. - * e.g. await sleep(1000), pauses the async flow execution for 1 second. - */ -export function sleep(milliSeconds: number): Promise { - return new Promise(resolve => { setTimeout(resolve, milliSeconds); }); -} - -export function nextTick(): Promise { - return new Promise(resolve => { process.nextTick(resolve); }); -} - -/** - * Executes a provided callback only if a promise takes longer than - * `milliSeconds` milliseconds to resolve. - * - * @param `promise` the promise to wait on. - * @param `milliSeconds` max amount of time that `promise` can take to resolve - * before timeoutFn is fired. - * @param `timeoutFn` the function to execute when a promise takes longer than - * `milliSeconds` ms to resolve. - * @param `cleanupFn` the cleanup function to execute after the promise resolves. - */ -export async function triggerAfterWait( - promise: Promise, - milliSeconds: number, - timeoutFn: () => void, - cleanupFn?: () => void, -): Promise { - const timeout = setTimeout(timeoutFn, milliSeconds); - try { - return await promise; - } finally { - clearTimeout(timeout); - if (cleanupFn) { - cleanupFn(); - } - } +function sleep(milliSeconds) { + return new Promise(resolve => { + setTimeout(resolve, milliSeconds); + }); } -/** - * Returns a Promise that resolves to the same value as the given promise, or rejects if it takes - * longer than `milliseconds` milliseconds - */ -export function timeoutPromise( - promise: Promise, - milliseconds: number, -): Promise { +function nextTick() { + return new Promise(resolve => { + process.nextTick(resolve); + }); +}function timeoutPromise(promise, milliseconds) { return new Promise((resolve, reject) => { - let timeout = setTimeout( - () => { - timeout = null; - reject(new Error(`Promise timed out after ${String(milliseconds)} ms`)); - }, - milliseconds, - ); + let timeout = setTimeout(() => { + timeout = null; + reject(new Error(`Promise timed out after ${String(milliseconds)} ms`)); + }, milliseconds); promise.then(value => { if (timeout != null) { clearTimeout(timeout); @@ -169,87 +378,12 @@ export function timeoutPromise( reject(value); }); }); -} - -/** - * Call an async function repeatedly with a maximum number of trials limit, - * until a valid result that's defined by a validation function. - * A failed call can result from an async thrown exception, or invalid result. - * - * @param `retryFunction` the async logic that's wanted to be retried. - * @param `validationFunction` the validation function that decides whether a response is valid. - * @param `maximumTries` the number of times the `retryFunction` can fail to get a valid - * response before the `retryLimit` is terminated reporting an error. - * @param `retryIntervalMs` optional, the number of milliseconds to wait between trials, if wanted. - * - * If an exception is encountered on the last trial, the exception is thrown. - * If no valid response is found, an exception is thrown. - */ -export async function retryLimit( - retryFunction: () => Promise, - validationFunction: (result: T) => boolean, - maximumTries: number, - retryIntervalMs?: number = 0, -): Promise { - let result = null; - let tries = 0; - let lastError = null; - while (tries === 0 || tries < maximumTries) { - try { - // eslint-disable-next-line no-await-in-loop - result = await retryFunction(); - lastError = null; - if (validationFunction(result)) { - return result; - } - } catch (error) { - lastError = error; - result = null; - } - - if (++tries < maximumTries && retryIntervalMs !== 0) { - // eslint-disable-next-line no-await-in-loop - await sleep(retryIntervalMs); - } - } - if (lastError != null) { - throw lastError; - } else if (tries === maximumTries) { - throw new Error('No valid response found!'); - } else { - return ((result: any): T); - } -} - -/** - * Limits async function execution parallelism to only one at a time. - * Hence, if a call is already running, it will wait for it to finish, - * then start the next async execution, but if called again while not finished, - * it will return the scheduled execution promise. - * - * Sample Usage: - * ``` - * let i = 1; - * const oneExecAtATime = oneParallelAsyncCall(() => { - * return next Promise((resolve, reject) => { - * setTimeout(200, () => resolve(i++)); - * }); - * }); - * - * const result1Promise = oneExecAtATime(); // Start an async, and resolve to 1 in 200 ms. - * const result2Promise = oneExecAtATime(); // Schedule the next async, and resolve to 2 in 400 ms. - * const result3Promise = oneExecAtATime(); // Reuse scheduled promise and resolve to 2 in 400 ms. - * ``` - */ -export function serializeAsyncCall(asyncFun: () => Promise): () => Promise { +}function serializeAsyncCall(asyncFun) { let scheduledCall = null; let pendingCall = null; const startAsyncCall = () => { const resultPromise = asyncFun(); - pendingCall = resultPromise.then( - () => (pendingCall = null), - () => (pendingCall = null), - ); + pendingCall = resultPromise.then(() => pendingCall = null, () => pendingCall = null); return resultPromise; }; const callNext = () => { @@ -258,7 +392,10 @@ export function serializeAsyncCall(asyncFun: () => Promise): () => Promise }; const scheduleNextCall = () => { if (scheduledCall == null) { - invariant(pendingCall, 'pendingCall must not be null!'); + if (!pendingCall) { + throw new Error('pendingCall must not be null!'); + } + scheduledCall = pendingCall.then(callNext, callNext); } return scheduledCall; @@ -279,10 +416,7 @@ export function serializeAsyncCall(asyncFun: () => Promise): () => Promise * IMPORTANT: This should almost never be used!! Instead, use the Promise constructor. See * */ -export class Deferred { - promise: Promise; - resolve: (value: T) => void; - reject: (error: Error) => void; +class Deferred { constructor() { this.promise = new Promise((resolve, reject) => { @@ -292,29 +426,26 @@ export class Deferred { } } -/** - * Returns a value derived asynchronously from an element in the items array. - * The test function is applied sequentially to each element in items until - * one returns a Promise that resolves to a non-null value. When this happens, - * the Promise returned by this method will resolve to that non-null value. If - * no such Promise is produced, then the Promise returned by this function - * will resolve to null. - * - * @param items Array of elements that will be passed to test, one at a time. - * @param test Will be called with each item and must return either: - * (1) A "thenable" (i.e, a Promise or promise-like object) that resolves - * to a derived value (that will be returned) or null. - * (2) null. - * In both cases where null is returned, test will be applied to the next - * item in the array. - * @param thisArg Receiver that will be used when test is called. - * @return Promise that resolves to an asynchronously derived value or null. - */ -export function asyncFind( - items_: Array, - test: (t: T) => ?Promise, - thisArg?: mixed, -): Promise { +exports.Deferred = Deferred; /** + * Returns a value derived asynchronously from an element in the items array. + * The test function is applied sequentially to each element in items until + * one returns a Promise that resolves to a non-null value. When this happens, + * the Promise returned by this method will resolve to that non-null value. If + * no such Promise is produced, then the Promise returned by this function + * will resolve to null. + * + * @param items Array of elements that will be passed to test, one at a time. + * @param test Will be called with each item and must return either: + * (1) A "thenable" (i.e, a Promise or promise-like object) that resolves + * to a derived value (that will be returned) or null. + * (2) null. + * In both cases where null is returned, test will be applied to the next + * item in the array. + * @param thisArg Receiver that will be used when test is called. + * @return Promise that resolves to an asynchronously derived value or null. + */ + +function asyncFind(items_, test, thisArg) { let items = items_; return new Promise((resolve, reject) => { // Create a local copy of items to defend against the caller modifying the @@ -322,29 +453,33 @@ export function asyncFind( items = items.slice(); const numItems = items.length; - const next = async function(index) { - if (index === numItems) { - resolve(null); - return; - } + const next = (() => { + var _ref3 = (0, _asyncToGenerator.default)(function* (index) { + if (index === numItems) { + resolve(null); + return; + } - const item = items[index]; - const result = await test.call(thisArg, item); - if (result !== null) { - resolve(result); - } else { - next(index + 1); - } - }; + const item = items[index]; + const result = yield test.call(thisArg, item); + if (result !== null) { + resolve(result); + } else { + next(index + 1); + } + }); + + return function next(_x8) { + return _ref3.apply(this, arguments); + }; + })(); next(0); }); } -export function denodeify( - f: (...args: Array) => any, -): (...args: Array) => Promise { - return function(...args: Array) { +function denodeify(f) { + return function (...args) { return new Promise((resolve, reject) => { function callback(error, result) { if (error) { @@ -374,136 +509,43 @@ export function denodeify( * @param limit the configurable number of parallel async operations. * @param mappingFunction the async Promise function that could return a useful result. */ -export function asyncLimit( - array: Array, - limit: number, - mappingFunction: (item: T) => Promise, -): Promise> { - const result: Array = new Array(array.length); +function asyncLimit(array, limit, mappingFunction) { + const result = new Array(array.length); let parallelPromises = 0; let index = 0; let parallelLimit = Math.min(limit, array.length) || 1; return new Promise((resolve, reject) => { - const runPromise = async () => { - if (index === array.length) { - if (parallelPromises === 0) { - resolve(result); + const runPromise = (() => { + var _ref4 = (0, _asyncToGenerator.default)(function* () { + if (index === array.length) { + if (parallelPromises === 0) { + resolve(result); + } + return; } - return; - } - ++parallelPromises; - const i = index++; - try { - result[i] = await mappingFunction(array[i]); - } catch (e) { - reject(e); - } - --parallelPromises; - runPromise(); - }; + ++parallelPromises; + const i = index++; + try { + result[i] = yield mappingFunction(array[i]); + } catch (e) { + reject(e); + } + --parallelPromises; + runPromise(); + }); + + return function runPromise() { + return _ref4.apply(this, arguments); + }; + })(); while (parallelLimit--) { runPromise(); } }); -} - -/** - * `filter` Promise utility that allows filtering an array with an async Promise function. - * It's an alternative to `Array.prototype.filter` that accepts an async function. - * You can optionally configure a limit to set the maximum number of async operations at a time. - * - * Previously, with the `Promise.all` primitive, we can't set the parallelism limit and we have to - * `filter`, so, we replace the old `filter` code: - * var existingFilePaths = []; - * await Promise.all(filePaths.map(async (filePath) => { - * if (await fsPromise.exists(filePath)) { - * existingFilePaths.push(filePath); - * } - * })); - * with limit 5 parallel filesystem operations at a time: - * var existingFilePaths = await asyncFilter(filePaths, fsPromise.exists, 5); - * - * @param array the array of items for `filter`ing. - * @param filterFunction the async `filter` function that returns a Promise that resolves to a - * boolean. - * @param limit the configurable number of parallel async operations. - */ -export async function asyncFilter( - array: Array, - filterFunction: (item: T) => Promise, - limit?: number, -): Promise> { - const filteredList = []; - await asyncLimit(array, limit || array.length, async (item: T) => { - if (await filterFunction(item)) { - filteredList.push(item); - } - }); - return filteredList; -} - -export async function asyncObjFilter( - obj: {[key: string]: T}, - filterFunction: (item: T, key: string) => Promise, - limit?: number, -): Promise<{[key: string]: T}> { - const keys = Object.keys(obj); - const filteredObj = {}; - await asyncLimit(keys, limit || keys.length, async (key: string) => { - const item = obj[key]; - if (await filterFunction(item, key)) { - filteredObj[key] = item; - } - }); - return filteredObj; -} - -/** - * `some` Promise utility that allows `some` an array with an async Promise some function. - * It's an alternative to `Array.prototype.some` that accepts an async some function. - * You can optionally configure a limit to set the maximum number of async operations at a time. - * - * Previously, with the Promise.all primitive, we can't set the parallelism limit and we have to - * `some`, so, we replace the old `some` code: - * var someFileExist = false; - * await Promise.all(filePaths.map(async (filePath) => { - * if (await fsPromise.exists(filePath)) { - * someFileExist = true; - * } - * })); - * with limit 5 parallel filesystem operations at a time: - * var someFileExist = await asyncSome(filePaths, fsPromise.exists, 5); - * - * @param array the array of items for `some`ing. - * @param someFunction the async `some` function that returns a Promise that resolves to a - * boolean. - * @param limit the configurable number of parallel async operations. - */ -export async function asyncSome( - array: Array, - someFunction: (item: T) => Promise, - limit?: number, -): Promise { - let resolved = false; - await asyncLimit(array, limit || array.length, async (item: T) => { - if (resolved) { - // We don't need to call the someFunction anymore or wait any longer. - return; - } - if (await someFunction(item)) { - resolved = true; - } - }); - return resolved; -} - -/** - * Check if an object is Promise by testing if it has a `then` function property. - */ -export function isPromise(object: any): boolean { +}function isPromise(object) { return Boolean(object) && typeof object === 'object' && typeof object.then === 'function'; } @@ -511,16 +553,10 @@ export function isPromise(object: any): boolean { * We can't name a function 'finally', so use lastly instead. * fn() will be executed (and completed) after the provided promise resolves/rejects. */ -export function lastly( - promise: Promise, - fn: () => Promise | mixed, -): Promise { - return promise - .then(ret => { - return Promise.resolve(fn()) - .then(() => ret); - }, err => { - return Promise.resolve(fn()) - .then(() => Promise.reject(err)); - }); -} +function lastly(promise, fn) { + return promise.then(ret => { + return Promise.resolve(fn()).then(() => ret); + }, err => { + return Promise.resolve(fn()).then(() => Promise.reject(err)); + }); +} \ No newline at end of file diff --git a/pkg/commons-node/range.js b/pkg/commons-node/range.js index 501dca95cf..dc042820f9 100644 --- a/pkg/commons-node/range.js +++ b/pkg/commons-node/range.js @@ -1,3 +1,10 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.wordAtPositionFromBuffer = wordAtPositionFromBuffer; +exports.matchRegexEndingAt = matchRegexEndingAt; /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,20 +12,16 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * */ -export function wordAtPositionFromBuffer( - buffer: atom$TextBuffer | simpleTextBuffer$TextBuffer, - position: atom$PointObject, - wordRegex: RegExp, -): ?{wordMatch: Array, range: atom$Range} { - const {row, column} = position; +function wordAtPositionFromBuffer(buffer, position, wordRegex) { + const { row, column } = position; const rowRange = buffer.rangeForRow(row); let matchData; // Extract the expression from the row text. buffer.scanInRange(wordRegex, rowRange, data => { - const {range} = data; + const { range } = data; if (range.containsPoint(position)) { matchData = data; } @@ -30,7 +33,7 @@ export function wordAtPositionFromBuffer( if (matchData) { return { wordMatch: matchData.match, - range: matchData.range, + range: matchData.range }; } else { return null; @@ -40,12 +43,8 @@ export function wordAtPositionFromBuffer( // Matches a regex on the text of the line ending at endPosition. // regex should end with a '$'. // Useful for autocomplete. -export function matchRegexEndingAt( - buffer: atom$TextBuffer | simpleTextBuffer$TextBuffer, - endPosition: atom$PointObject, - regex: RegExp, -): ?string { +function matchRegexEndingAt(buffer, endPosition, regex) { const line = buffer.getTextInRange([[endPosition.row, 0], endPosition]); const match = regex.exec(line); return match == null ? null : match[0]; -} +} \ No newline at end of file diff --git a/pkg/commons-node/redux-observable.js b/pkg/commons-node/redux-observable.js index d07f0ec5d6..679a9e5e95 100644 --- a/pkg/commons-node/redux-observable.js +++ b/pkg/commons-node/redux-observable.js @@ -1,12 +1,32 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the license found in the LICENSE file in - * the root directory of this source tree. - * - * @flow - */ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.ActionsObservable = undefined; +exports.combineEpics = combineEpics; +exports.createEpicMiddleware = createEpicMiddleware; + +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js'); + +// This should be { type: readonly string } when we get readonly props. Because this is used with +// disjoint unions we can't use `string` here due to mutation concerns. Flow doesn't know that we +// aren't going to mutate the objects with a random string value so it can't allow us to pass a +// specific action type into something of type { type: string } +function combineEpics(...epics) { + return (actions, store, extra) => { + const streams = epics.map(epic => epic(actions, store, extra)); + return _rxjsBundlesRxMinJs.Observable.merge(...streams); + }; +} /** + * Copyright (c) 2015-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the license found in the LICENSE file in + * the root directory of this source tree. + * + * + */ // Derived from because their version // imports an Rx operator module and we use a bundle. Original license follows: @@ -33,37 +53,15 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. -import {Observable, Subject} from 'rxjs'; - -// This should be { type: readonly string } when we get readonly props. Because this is used with -// disjoint unions we can't use `string` here due to mutation concerns. Flow doesn't know that we -// aren't going to mutate the objects with a random string value so it can't allow us to pass a -// specific action type into something of type { type: string } -type Action = {type: any}; -type Store = { - dispatch(action: T): void, - getState(): U, -}; -type Next = (action: T) => T; -export type Epic = - (actions: ActionsObservable, store: Store, extra: E) => Observable; - -export function combineEpics(...epics: Array>): Epic { - return (actions: ActionsObservable, store: Store, extra: E) => { - const streams: Array> = epics.map(epic => epic(actions, store, extra)); - return Observable.merge(...streams); - }; -} - -export function createEpicMiddleware(rootEpic?: Epic) { - const actions = new Subject(); +function createEpicMiddleware(rootEpic) { + const actions = new _rxjsBundlesRxMinJs.Subject(); const actionsObs = new ActionsObservable(actions); - return (store: Store) => (next: Next) => { + return store => next => { if (rootEpic != null) { rootEpic(actionsObs, store).subscribe(store.dispatch); } - return (action: T) => { + return action => { const result = next(action); actions.next(action); return result; @@ -71,23 +69,21 @@ export function createEpicMiddleware(rootEpic?: Epic) }; } -export class ActionsObservable extends Observable { - source: Observable; - operator: any; +class ActionsObservable extends _rxjsBundlesRxMinJs.Observable { - constructor(actionsSubject: Observable) { + constructor(actionsSubject) { super(); this.source = actionsSubject; } - lift(operator: any): Observable { + lift(operator) { const observable = new ActionsObservable(this); observable.operator = operator; return observable; } - ofType(...keys: Array): ActionsObservable { - const result = this.filter(({type}) => { + ofType(...keys) { + const result = this.filter(({ type }) => { const len = keys.length; if (len === 1) { return type === keys[0]; @@ -100,6 +96,7 @@ export class ActionsObservable extends Observable { } return false; }); - return ((result: any): ActionsObservable); + return result; } } +exports.ActionsObservable = ActionsObservable; \ No newline at end of file diff --git a/pkg/commons-node/runtime-info.js b/pkg/commons-node/runtime-info.js index 69c5d2f058..6e2d320698 100644 --- a/pkg/commons-node/runtime-info.js +++ b/pkg/commons-node/runtime-info.js @@ -1,3 +1,32 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.getRuntimeInformation = getRuntimeInformation; + +var _systemInfo; + +function _load_systemInfo() { + return _systemInfo = require('./system-info'); +} + +var _os = _interopRequireDefault(require('os')); + +var _uuid; + +function _load_uuid() { + return _uuid = _interopRequireDefault(require('uuid')); +} + +var _env; + +function _load_env() { + return _env = require('../nuclide-node-transpiler/lib/env'); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,63 +34,38 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * */ -import { - getOsType, - getAtomVersion, - getNuclideVersion, - isRunningInClient, -} from './system-info'; -import os from 'os'; -import uuid from 'uuid'; -import {__DEV__} from '../nuclide-node-transpiler/lib/env'; - -export type RuntimeInformation = { - sessionId: string, - user: string, - osType: string, - timestamp: number, - isClient: boolean, - isDevelopment: boolean, - atomVersion: string, - nuclideVersion: string, - installerPackageVersion: number, - serverVersion: number, - uptime: number, -}; - let cachedInformation = null; -function getCacheableRuntimeInformation(): RuntimeInformation { +function getCacheableRuntimeInformation() { if (cachedInformation !== null) { return cachedInformation; } cachedInformation = { - sessionId: uuid.v4(), - user: os.userInfo().username, - osType: getOsType(), + sessionId: (_uuid || _load_uuid()).default.v4(), + user: _os.default.userInfo().username, + osType: (0, (_systemInfo || _load_systemInfo()).getOsType)(), timestamp: 0, - isClient: isRunningInClient(), - isDevelopment: __DEV__, - atomVersion: isRunningInClient() ? getAtomVersion() : '', - nuclideVersion: getNuclideVersion(), + isClient: (0, (_systemInfo || _load_systemInfo()).isRunningInClient)(), + isDevelopment: (_env || _load_env()).__DEV__, + atomVersion: (0, (_systemInfo || _load_systemInfo()).isRunningInClient)() ? (0, (_systemInfo || _load_systemInfo()).getAtomVersion)() : '', + nuclideVersion: (0, (_systemInfo || _load_systemInfo()).getNuclideVersion)(), installerPackageVersion: 0, uptime: 0, // TODO (chenshen) fill following information. - serverVersion: 0, + serverVersion: 0 }; return cachedInformation; } -export function getRuntimeInformation(): RuntimeInformation { - const runtimeInformation = { - ...getCacheableRuntimeInformation(), +function getRuntimeInformation() { + const runtimeInformation = Object.assign({}, getCacheableRuntimeInformation(), { timestamp: Date.now(), - uptime: Math.floor(process.uptime() * 1000), - }; + uptime: Math.floor(process.uptime() * 1000) + }); return runtimeInformation; -} +} \ No newline at end of file diff --git a/pkg/commons-node/scheduleIdleCallback.js b/pkg/commons-node/scheduleIdleCallback.js index 5ebd7ef1d8..f85636d4b4 100644 --- a/pkg/commons-node/scheduleIdleCallback.js +++ b/pkg/commons-node/scheduleIdleCallback.js @@ -1,12 +1,59 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the license found in the LICENSE file in - * the root directory of this source tree. - * - * @flow - */ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = global.requestIdleCallback ? +// Using Browser API +// Is guaranteed to resolve after `timeout` milliseconds. +function scheduleIdleCallback(callback_, options = {}) { + const afterRemainingTime = options.afterRemainingTime || 49; + const timeout = options.timeout || 500; + let callback = callback_; + let id; + const startTime = Date.now(); + function fn(deadline) { + if (deadline.timeRemaining() >= afterRemainingTime || Date.now() - startTime >= timeout) { + if (!(callback != null)) { + throw new Error('Invariant violation: "callback != null"'); + } + + callback(deadline); + id = callback = null; + } else { + id = global.requestIdleCallback(fn, { + timeout: timeout - (Date.now() - startTime) + }); + } + } + id = global.requestIdleCallback(fn, { timeout }); + return { + dispose() { + if (id != null) { + global.cancelIdleCallback(id); + id = callback = null; + } + } + }; +} : + +// Using Node API +function scheduleIdleCallback(callback, options) { + const id = global.setImmediate(callback); + return { + dispose() { + global.clearImmediate(id); + } + }; +}; /** + * Copyright (c) 2015-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the license found in the LICENSE file in + * the root directory of this source tree. + * + * + */ /** * `scheduleIdleCallback` is a wrapper around `requestIdleCallback` that: @@ -20,58 +67,4 @@ * `requestIdleCallback` for so much time to become available. */ -import invariant from 'assert'; - -export default global.requestIdleCallback ? - // Using Browser API - // Is guaranteed to resolve after `timeout` milliseconds. - function scheduleIdleCallback( - callback_: () => void, - options?: { - afterRemainingTime?: 30 | 40 | 49, - timeout?: number, - } = {}, - ): IDisposable { - const afterRemainingTime = options.afterRemainingTime || 49; - const timeout = options.timeout || 500; - let callback = callback_; - let id; - const startTime = Date.now(); - function fn(deadline) { - if (deadline.timeRemaining() >= afterRemainingTime || - Date.now() - startTime >= timeout) { - invariant(callback != null); - callback(deadline); - id = callback = null; - } else { - id = global.requestIdleCallback(fn, { - timeout: timeout - (Date.now() - startTime), - }); - } - } - id = global.requestIdleCallback(fn, {timeout}); - return { - dispose() { - if (id != null) { - global.cancelIdleCallback(id); - id = callback = null; - } - }, - }; - } : - - // Using Node API - function scheduleIdleCallback( - callback: () => void, - options?: { - afterRemainingTime?: 30 | 40 | 49, - timeout?: number, - }, - ) { - const id = global.setImmediate(callback); - return { - dispose() { - global.clearImmediate(id); - }, - }; - }; +module.exports = exports['default']; \ No newline at end of file diff --git a/pkg/commons-node/singleton.js b/pkg/commons-node/singleton.js index 6654c62189..49c8b2dc2a 100644 --- a/pkg/commons-node/singleton.js +++ b/pkg/commons-node/singleton.js @@ -1,3 +1,8 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,13 +10,12 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * */ - const GLOBAL_MAP_NAME = '__NUCLIDE_SINGLETONS__'; -function getMap(): Map { +function getMap() { let map = global[GLOBAL_MAP_NAME]; if (!map) { map = global[GLOBAL_MAP_NAME] = new Map(); @@ -24,7 +28,7 @@ function getMap(): Map { * constructor will be called exactly once, future invocations will * return the result of the constructor call. */ -function get(field: string, constructor: () => T): T { +function get(field, constructor) { const map = getMap(); if (!map.has(field)) { map.set(field, constructor()); @@ -33,20 +37,21 @@ function get(field: string, constructor: () => T): T { // because we have just checked it above. However, we cannot just call `get` and then check it // against null because T may be a nullable type, in which case this would break subtly. So, we // circumvent the type system here to maintain the desired runtime behavior. - return (map.get(field): any); + return map.get(field); } -function clear(field: string): void { +function clear(field) { getMap().delete(field); } -function reset(field: string, constructor: () => T): T { +function reset(field, constructor) { clear(field); return get(field, constructor); } -export default { +exports.default = { get, clear, - reset, + reset }; +module.exports = exports['default']; \ No newline at end of file diff --git a/pkg/commons-node/spec/BatchProcessedQueue-spec.js b/pkg/commons-node/spec/BatchProcessedQueue-spec.js deleted file mode 100644 index 0a0684fb7a..0000000000 --- a/pkg/commons-node/spec/BatchProcessedQueue-spec.js +++ /dev/null @@ -1,34 +0,0 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the license found in the LICENSE file in - * the root directory of this source tree. - * - * @flow - */ - -import BatchProcessedQueue from '../BatchProcessedQueue'; - -describe('analytics - BatchProcessedQueue', () => { - it('regular operation', () => { - const handler = jasmine.createSpy('handler'); - const queue = new BatchProcessedQueue(5000, handler); - - queue.add(1); - queue.add(2); - queue.add(3); - queue.add(4); - queue.add(5); - expect(handler).not.toHaveBeenCalled(); - - advanceClock(4999); - expect(handler).not.toHaveBeenCalled(); - advanceClock(1); - expect(handler).toHaveBeenCalledWith([1, 2, 3, 4, 5]); - - queue.add(42); - advanceClock(10000); - expect(handler).toHaveBeenCalledWith([42]); - }); -}); diff --git a/pkg/commons-node/spec/ConfigCache-spec.js b/pkg/commons-node/spec/ConfigCache-spec.js deleted file mode 100644 index b004450f23..0000000000 --- a/pkg/commons-node/spec/ConfigCache-spec.js +++ /dev/null @@ -1,34 +0,0 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the license found in the LICENSE file in - * the root directory of this source tree. - * - * @flow - */ - -import {ConfigCache} from '../ConfigCache'; -import nuclideUri from '../nuclideUri'; - -const CONFIG_FILE_NAME = '.test_nuclide_config_file'; - -describe('ConfigCache', () => { - const noConfigFolder = nuclideUri.join(__dirname, 'fixtures'); - const rootFolder = nuclideUri.join(__dirname, 'fixtures/ConfigCache'); - const rootFile = nuclideUri.join(__dirname, 'fixtures/ConfigCache/file'); - const nestedFolder = nuclideUri.join(__dirname, 'fixtures/ConfigCache/testFolder'); - const nestedFile = nuclideUri.join(__dirname, 'fixtures/ConfigCache/testFolder/file'); - - it('ConfigCache', () => { - waitsForPromise(async () => { - const cache = new ConfigCache(CONFIG_FILE_NAME); - - expect(await (cache.getConfigDir(noConfigFolder))).toBe(null); - expect(await (cache.getConfigDir(rootFolder))).toBe(rootFolder); - expect(await (cache.getConfigDir(rootFile))).toBe(rootFolder); - expect(await (cache.getConfigDir(nestedFolder))).toBe(rootFolder); - expect(await (cache.getConfigDir(nestedFile))).toBe(rootFolder); - }); - }); -}); diff --git a/pkg/commons-node/spec/Dispatcher-spec.js b/pkg/commons-node/spec/Dispatcher-spec.js deleted file mode 100644 index 1a200e89a6..0000000000 --- a/pkg/commons-node/spec/Dispatcher-spec.js +++ /dev/null @@ -1,214 +0,0 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the license found in the LICENSE file in - * the root directory of this source tree. - * - * @flow - */ - -/** - * Originally from https://github.com/facebook/flux/blob/55480fb/src/Dispatcher.js - */ - -import Dispatcher from '../Dispatcher'; - -describe('Dispatcher', () => { - let dispatcher; - let callbackA; - let callbackB; - - beforeEach(() => { - dispatcher = new Dispatcher(); - callbackA = jasmine.createSpy('callbackA'); - callbackB = jasmine.createSpy('callbackB'); - }); - - it('should execute all subscriber callbacks', () => { - dispatcher.register(callbackA); - dispatcher.register(callbackB); - - const payload = {}; - dispatcher.dispatch(payload); - - expect(callbackA.calls.length).toBe(1); - expect(callbackA.calls[0].args[0]).toBe(payload); - - expect(callbackB.calls.length).toBe(1); - expect(callbackB.calls[0].args[0]).toBe(payload); - - dispatcher.dispatch(payload); - - expect(callbackA.calls.length).toBe(2); - expect(callbackA.calls[1].args[0]).toBe(payload); - - expect(callbackB.calls.length).toBe(2); - expect(callbackB.calls[1].args[0]).toBe(payload); - }); - - it('should wait for callbacks registered earlier', () => { - const tokenA = dispatcher.register(callbackA); - - dispatcher.register(payload => { - dispatcher.waitFor([tokenA]); - expect(callbackA.calls.length).toBe(1); - expect(callbackA.calls[0].args[0]).toBe(payload); - callbackB(payload); - }); - - const payload = {}; - dispatcher.dispatch(payload); - - expect(callbackA.calls.length).toBe(1); - expect(callbackA.calls[0].args[0]).toBe(payload); - - expect(callbackB.calls.length).toBe(1); - expect(callbackB.calls[0].args[0]).toBe(payload); - }); - - it('should wait for callbacks registered later', () => { - dispatcher.register(payload => { - dispatcher.waitFor([tokenB]); - expect(callbackB.calls.length).toBe(1); - expect(callbackB.calls[0].args[0]).toBe(payload); - callbackA(payload); - }); - - const tokenB = dispatcher.register(callbackB); - - const payload = {}; - dispatcher.dispatch(payload); - - expect(callbackA.calls.length).toBe(1); - expect(callbackA.calls[0].args[0]).toBe(payload); - - expect(callbackB.calls.length).toBe(1); - expect(callbackB.calls[0].args[0]).toBe(payload); - }); - - it('should throw if dispatch() while dispatching', () => { - dispatcher.register(payload => { - dispatcher.dispatch(payload); - callbackA(); - }); - - const payload = {}; - expect(() => dispatcher.dispatch(payload)).toThrow(); - expect(callbackA.calls.length).toBe(0); - }); - - it('should throw if waitFor() while not dispatching', () => { - const tokenA = dispatcher.register(callbackA); - - expect(() => dispatcher.waitFor([tokenA])).toThrow(); - expect(callbackA.calls.length).toBe(0); - }); - - it('should throw if waitFor() with invalid token', () => { - const invalidToken = 1337; - - dispatcher.register(() => { - // $FlowIgnore: Purposefully invalid token. - dispatcher.waitFor([invalidToken]); - }); - - const payload = {}; - expect(() => dispatcher.dispatch(payload)).toThrow(); - }); - - it('should throw on self-circular dependencies', () => { - const tokenA = dispatcher.register(payload => { - dispatcher.waitFor([tokenA]); - callbackA(payload); - }); - - const payload = {}; - expect(() => dispatcher.dispatch(payload)).toThrow(); - expect(callbackA.calls.length).toBe(0); - }); - - it('should throw on multi-circular dependencies', () => { - const tokenA = dispatcher.register(payload => { - dispatcher.waitFor([tokenB]); - callbackA(payload); - }); - - const tokenB = dispatcher.register(payload => { - dispatcher.waitFor([tokenA]); - callbackB(payload); - }); - - expect(() => dispatcher.dispatch({})).toThrow(); - expect(callbackA.calls.length).toBe(0); - expect(callbackB.calls.length).toBe(0); - }); - - it('should remain in a consistent state after a failed dispatch', () => { - dispatcher.register(callbackA); - dispatcher.register(payload => { - if (payload.shouldThrow) { - throw new Error(); - } - callbackB(); - }); - - expect(() => dispatcher.dispatch({shouldThrow: true})).toThrow(); - - // Cannot make assumptions about a failed dispatch. - const callbackACount = callbackA.calls.length; - - dispatcher.dispatch({shouldThrow: false}); - - expect(callbackA.calls.length).toBe(callbackACount + 1); - expect(callbackB.calls.length).toBe(1); - }); - - it('should properly unregister callbacks', () => { - dispatcher.register(callbackA); - - const tokenB = dispatcher.register(callbackB); - - const payload = {}; - dispatcher.dispatch(payload); - - expect(callbackA.calls.length).toBe(1); - expect(callbackA.calls[0].args[0]).toBe(payload); - - expect(callbackB.calls.length).toBe(1); - expect(callbackB.calls[0].args[0]).toBe(payload); - - dispatcher.unregister(tokenB); - - dispatcher.dispatch(payload); - - expect(callbackA.calls.length).toBe(2); - expect(callbackA.calls[1].args[0]).toBe(payload); - - expect(callbackB.calls.length).toBe(1); - }); - - it('should throw if register() while dispatching', () => { - dispatcher.register(payload => { - dispatcher.register(callbackB); - callbackA(); - }); - - const payload = {}; - expect(() => dispatcher.dispatch(payload)).toThrow(); - expect(callbackA.calls.length).toBe(0); - }); - - it('should throw if unregister() while dispatching', () => { - const tokenA = dispatcher.register(callbackA); - dispatcher.register(payload => { - dispatcher.unregister(tokenA); - callbackB(); - }); - - const payload = {}; - expect(() => dispatcher.dispatch(payload)).toThrow(); - expect(callbackA.calls.length).toBe(1); - expect(callbackB.calls.length).toBe(0); - }); -}); diff --git a/pkg/commons-node/spec/Hasher-spec.js b/pkg/commons-node/spec/Hasher-spec.js deleted file mode 100644 index 7a0de36d2e..0000000000 --- a/pkg/commons-node/spec/Hasher-spec.js +++ /dev/null @@ -1,44 +0,0 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the license found in the LICENSE file in - * the root directory of this source tree. - * - * @flow - */ - -import Hasher from '../Hasher'; - -describe('Hasher', () => { - it('creates a new hash for each object', () => { - const a = {}; - const b = {}; - const hasher = new Hasher(); - expect(hasher.getHash(a)).not.toBe(hasher.getHash(b)); - }); - - it('returns the same hash for the same object', () => { - const a = {}; - const hasher = new Hasher(); - expect(hasher.getHash(a)).toBe(hasher.getHash(a)); - }); - - it('works for numbers', () => { - const hasher = new Hasher(); - expect(hasher.getHash(1)).toBe(hasher.getHash(1)); - expect(hasher.getHash(1)).not.toBe(hasher.getHash(2)); - }); - - it('works for booleans', () => { - const hasher = new Hasher(); - expect(hasher.getHash(true)).toBe(hasher.getHash(true)); - expect(hasher.getHash(true)).not.toBe(hasher.getHash(false)); - }); - - it('works for strings', () => { - const hasher = new Hasher(); - expect(hasher.getHash('a')).toBe(hasher.getHash('a')); - expect(hasher.getHash('a')).not.toBe(hasher.getHash('b')); - }); -}); diff --git a/pkg/commons-node/spec/ScribeProcess-spec.js b/pkg/commons-node/spec/ScribeProcess-spec.js deleted file mode 100644 index cd40c6d72d..0000000000 --- a/pkg/commons-node/spec/ScribeProcess-spec.js +++ /dev/null @@ -1,88 +0,0 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the license found in the LICENSE file in - * the root directory of this source tree. - * - * @flow - */ - -import nuclideUri from '../nuclideUri'; -import fsPromise from '../fsPromise'; -import ScribeProcess, {__test__} from '../ScribeProcess'; - -describe('scribe_cat test suites', () => { - let tempDir = ''; - let scribeProcess: ?ScribeProcess = null; - let originalCommand = ''; - - async function getContentOfScribeCategory( - category: string, - ): Promise> { - const categoryFilePath = nuclideUri.join(tempDir, category); - const content = await fsPromise.readFile(categoryFilePath); - const result = content.toString().split('\n') - .filter(item => (item.length > 0)); - return result; - } - - beforeEach(() => { - jasmine.useRealClock(); - // Simulated scribe_cat script which saves data into: - // ${process.env['SCRIBE_MOCK_PATH'] + category_name} - // It terminates once we cut off the stdin stream. - const scribeCatMockCommandPath = nuclideUri.join( - nuclideUri.dirname(__filename), - 'scripts', - 'scribe_cat_mock', - ); - waitsForPromise(async () => { - tempDir = await fsPromise.tempdir(); - originalCommand = __test__.setScribeCatCommand(scribeCatMockCommandPath); - process.env.SCRIBE_MOCK_PATH = tempDir; - }); - }); - - afterEach(() => { - waitsForPromise(async () => { - if (scribeProcess) { - await scribeProcess.dispose(); - } - __test__.setScribeCatCommand(originalCommand); - }); - }); - - it('Saves data to scribe category', () => { - const localScribeProcess = scribeProcess = new ScribeProcess('test'); - - const messages = [ - 'A', 'nuclide', 'is', 'an', 'atomic', 'species', 'characterized', 'by', 'the', 'specific', - 'constitution', 'of', 'its', 'nucleus.', - ]; - waitsForPromise(async () => { - messages.map(message => localScribeProcess.write(message)); - // Wait for `scribe_cat_mock` to flush data into disk. - await localScribeProcess.join(); - expect(messages).toEqual(await getContentOfScribeCategory('test')); - }); - }); - - it('Saves data to scribe category and resume from error', () => { - const localScribeProcess = scribeProcess = new ScribeProcess('test'); - - const firstPart = 'A nuclide is an atomic species'.split(' '); - const secondPart = 'characterized by the specific constitution of its nucleus.'.split(' '); - - waitsForPromise(async () => { - firstPart.map(message => localScribeProcess.write(message)); - // Kill the existing process. - await localScribeProcess.join(); - secondPart.map(message => localScribeProcess.write(message)); - // Wait for `scribe_cat_mock` to flush data into disk. - await localScribeProcess.join(); - expect(firstPart.concat(secondPart)) - .toEqual(await getContentOfScribeCategory('test')); - }); - }); -}); diff --git a/pkg/commons-node/spec/SharedObservableCache-spec.js b/pkg/commons-node/spec/SharedObservableCache-spec.js deleted file mode 100644 index c34e4bd317..0000000000 --- a/pkg/commons-node/spec/SharedObservableCache-spec.js +++ /dev/null @@ -1,52 +0,0 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the license found in the LICENSE file in - * the root directory of this source tree. - * - * @flow - */ - -import {Subject} from 'rxjs'; -import SharedObservableCache from '../SharedObservableCache'; - -describe('SharedObservableCache', () => { - it('creates and deletes observables on demand', () => { - const mockObservable = new Subject(); - const mockFactory = jasmine.createSpy('factory') - .andReturn(mockObservable); - - const map = new SharedObservableCache(mockFactory); - const stream1 = map.get('key'); - const stream2 = map.get('key'); - - // The factory doesn't get called until the first subscription. - expect(mockFactory).not.toHaveBeenCalled(); - - const spy1 = jasmine.createSpy('spy1'); - const spy2 = jasmine.createSpy('spy2'); - - // The first subscription triggers observable creation. - const sub1 = stream1.subscribe(spy1); - expect(mockFactory.callCount).toBe(1); - - // The second subscription shouldn't. - const sub2 = stream2.subscribe(spy2); - expect(mockFactory.callCount).toBe(1); - - mockObservable.next('test'); - expect(spy1).toHaveBeenCalledWith('test'); - expect(spy2).toHaveBeenCalledWith('test'); - - sub1.unsubscribe(); - sub2.unsubscribe(); - - // Cache should be clear now. - expect(map._cache.size).toBe(0); - - const sub3 = stream1.subscribe(() => {}); - expect(mockFactory.callCount).toBe(2); - sub3.unsubscribe(); - }); -}); diff --git a/pkg/commons-node/spec/SimpleModel-spec.js b/pkg/commons-node/spec/SimpleModel-spec.js deleted file mode 100644 index 7bb9c7e72e..0000000000 --- a/pkg/commons-node/spec/SimpleModel-spec.js +++ /dev/null @@ -1,52 +0,0 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the license found in the LICENSE file in - * the root directory of this source tree. - * - * @flow - */ - -import {SimpleModel} from '../SimpleModel'; -import {Observable} from 'rxjs'; - -type State = { - count: number, - other: boolean, -}; - -class TestModel extends SimpleModel { - state: State; - constructor() { - super(); - this.state = { - count: 0, - other: true, - }; - } -} - -describe('SimpleModel', () => { - it('updates state when setState is called', () => { - const model = new TestModel(); - model.setState({count: 5}); - expect(model.state.count).toBe(5); - }); - - it('only changes the provided values when setState is called', () => { - const model = new TestModel(); - model.setState({count: 5}); - expect(model.state.other).toBe(true); - }); - - it('can be converted to an observable', () => { - waitsForPromise(async () => { - const model = new TestModel(); - // $FlowFixMe: Teach Flow about Symbol.observable - const states = Observable.from(model).take(2).toArray().toPromise(); - model.setState({count: 5}); - expect(await states).toEqual([{count: 0, other: true}, {count: 5, other: true}]); - }); - }); -}); diff --git a/pkg/commons-node/spec/UniversalDisposable-spec.js b/pkg/commons-node/spec/UniversalDisposable-spec.js deleted file mode 100644 index fbcd1df313..0000000000 --- a/pkg/commons-node/spec/UniversalDisposable-spec.js +++ /dev/null @@ -1,182 +0,0 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the license found in the LICENSE file in - * the root directory of this source tree. - * - * @flow - */ - -import UniversalDisposable from '../UniversalDisposable'; - -describe('UniversalDisposable', () => { - it('disposes of the Disposable arguments', () => { - const dispose = jasmine.createSpy('dispose'); - const universal = new UniversalDisposable({dispose}); - - expect(dispose.wasCalled).toBe(false); - universal.dispose(); - expect(dispose.callCount).toBe(1); - }); - - it('throws if you add after disposing', () => { - const universal = new UniversalDisposable(); - universal.dispose(); - expect(() => { universal.add(() => {}); }) - .toThrow('Cannot add to an already disposed UniversalDisposable!'); - }); - - it('calls function arguments', () => { - const foo = jasmine.createSpy('foo'); - const universal = new UniversalDisposable(foo); - - expect(foo.wasCalled).toBe(false); - universal.dispose(); - expect(foo.callCount).toBe(1); - }); - - it('calls unsubscribe arguments', () => { - const unsubscribe = jasmine.createSpy('unsubscribe'); - const universal = new UniversalDisposable(unsubscribe); - - expect(unsubscribe.wasCalled).toBe(false); - universal.dispose(); - expect(unsubscribe.callCount).toBe(1); - }); - - it('supports creation with mixed teardowns', () => { - const dispose = jasmine.createSpy('dispose'); - const unsubscribe = jasmine.createSpy('unsubscribe'); - const foo = jasmine.createSpy('foo'); - const universal = new UniversalDisposable( - {dispose}, - {unsubscribe}, - foo, - ); - - expect(dispose.wasCalled).toBe(false); - expect(unsubscribe.wasCalled).toBe(false); - expect(foo.wasCalled).toBe(false); - universal.dispose(); - expect(dispose.callCount).toBe(1); - expect(unsubscribe.callCount).toBe(1); - expect(foo.callCount).toBe(1); - }); - - it('supports adding mixed teardowns', () => { - const dispose = jasmine.createSpy('dispose'); - const unsubscribe = jasmine.createSpy('unsubscribe'); - const foo = jasmine.createSpy('foo'); - const universal = new UniversalDisposable(); - universal.add( - {dispose}, - {unsubscribe}, - foo, - ); - - expect(dispose.wasCalled).toBe(false); - expect(unsubscribe.wasCalled).toBe(false); - expect(foo.wasCalled).toBe(false); - universal.dispose(); - expect(dispose.callCount).toBe(1); - expect(unsubscribe.callCount).toBe(1); - expect(foo.callCount).toBe(1); - }); - - it('supports unsubscribe as well', () => { - const dispose = jasmine.createSpy('dispose'); - const unsubscribe = jasmine.createSpy('unsubscribe'); - const foo = jasmine.createSpy('foo'); - const universal = new UniversalDisposable( - {dispose}, - {unsubscribe}, - foo, - ); - - expect(dispose.wasCalled).toBe(false); - expect(unsubscribe.wasCalled).toBe(false); - expect(foo.wasCalled).toBe(false); - universal.unsubscribe(); - expect(dispose.callCount).toBe(1); - expect(unsubscribe.callCount).toBe(1); - expect(foo.callCount).toBe(1); - }); - - it('multiple dispose/unsubscribe calls have no effect', () => { - const dispose = jasmine.createSpy('dispose'); - const unsubscribe = jasmine.createSpy('unsubscribe'); - const foo = jasmine.createSpy('foo'); - const universal = new UniversalDisposable( - {dispose}, - {unsubscribe}, - foo, - ); - - expect(dispose.wasCalled).toBe(false); - expect(unsubscribe.wasCalled).toBe(false); - expect(foo.wasCalled).toBe(false); - universal.unsubscribe(); - universal.dispose(); - universal.unsubscribe(); - universal.dispose(); - expect(dispose.callCount).toBe(1); - expect(unsubscribe.callCount).toBe(1); - expect(foo.callCount).toBe(1); - }); - - it('supports removal of the teardowns', () => { - const dispose = {dispose: jasmine.createSpy('dispose')}; - const unsubscribe = {unsubscribe: jasmine.createSpy('unsubscribe')}; - const foo = jasmine.createSpy('foo'); - const universal = new UniversalDisposable( - dispose, - unsubscribe, - foo, - ); - - universal.remove(unsubscribe); - universal.remove(dispose, foo); - - universal.dispose(); - - expect(dispose.dispose.wasCalled).toBe(false); - expect(unsubscribe.unsubscribe.wasCalled).toBe(false); - expect(foo.wasCalled).toBe(false); - }); - - it('can clear all of the teardowns', () => { - const dispose = {dispose: jasmine.createSpy('dispose')}; - const unsubscribe = {unsubscribe: jasmine.createSpy('unsubscribe')}; - const foo = jasmine.createSpy('foo'); - const universal = new UniversalDisposable( - dispose, - unsubscribe, - foo, - ); - - universal.clear(); - - universal.dispose(); - - expect(dispose.dispose.wasCalled).toBe(false); - expect(unsubscribe.unsubscribe.wasCalled).toBe(false); - expect(foo.wasCalled).toBe(false); - }); - - it('maintains implicit order of the teardowns', () => { - const ids = []; - - const foo1 = () => ids.push(1); - const foo2 = () => ids.push(2); - const foo3 = () => ids.push(3); - const foo4 = () => ids.push(4); - - const universal = new UniversalDisposable(foo1, foo3); - universal.add(foo4, foo2); - - universal.dispose(); - - expect(ids).toEqual([1, 3, 4, 2]); - }); -}); diff --git a/pkg/commons-node/spec/cache-spec.js b/pkg/commons-node/spec/cache-spec.js deleted file mode 100644 index 762afd7290..0000000000 --- a/pkg/commons-node/spec/cache-spec.js +++ /dev/null @@ -1,107 +0,0 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the license found in the LICENSE file in - * the root directory of this source tree. - * - * @flow - */ - - -import {Cache} from '../cache'; - -describe('Cache', () => { - const key1 = 'key1'; - const key2 = 'key2'; - const value = 'value'; - - it('creates values on demand', () => { - let callCount = 0; - const factory = jasmine.createSpy('factory').andCallFake( - key => { - callCount += 1; - expect(key).toEqual(key1); - return value; - }); - const cache: Cache = new Cache(factory); - - expect(factory).not.toHaveBeenCalled(); - expect(cache.has(key1)).toEqual(false); - expect(cache.get(key1)).toEqual(value); - expect(callCount).toEqual(1); - expect(cache.has(key1)).toEqual(true); - expect(factory).toHaveBeenCalledWith(key1); - expect(Array.from(cache.values())).toEqual([value]); - - expect(cache.get(key1)).toEqual(value); - expect(callCount).toEqual(1); - }); - - it('delete', () => { - const factory = jasmine.createSpy('factory').andReturn(value); - const cache: Cache = new Cache(factory); - - expect(cache.delete(key1)).toEqual(false); - cache.get(key1); - expect(cache.has(key1)).toEqual(true); - expect(cache.delete(key1)).toEqual(true); - expect(cache.has(key1)).toEqual(false); - }); - - it('delete disposes values', () => { - const factory = jasmine.createSpy('factory').andReturn(value); - const dispose = jasmine.createSpy('dispose'); - const cache: Cache = new Cache(factory, dispose); - - cache.get(key1); - cache.delete(key1); - expect(dispose).toHaveBeenCalledWith(value); - }); - - it('clear disposes values', () => { - const factory = jasmine.createSpy('factory').andReturn(value); - const dispose = jasmine.createSpy('dispose'); - const cache: Cache = new Cache(factory, dispose); - - cache.get(key1); - cache.clear(); - expect(dispose).toHaveBeenCalledWith(value); - }); - - it('dispose disposes values', () => { - const factory = jasmine.createSpy('factory').andReturn(value); - const dispose = jasmine.createSpy('dispose'); - const cache: Cache = new Cache(factory, dispose); - - cache.get(key1); - cache.dispose(); - expect(dispose).toHaveBeenCalledWith(value); - }); - - it('observeValues sees existing and new values', () => { - waitsForPromise(async () => { - const factory = jasmine.createSpy('factory').andCallFake(key => key); - const cache: Cache = new Cache(factory); - - cache.get(key1); - const values = cache.observeValues().toArray().toPromise(); - cache.get(key2); - cache.dispose(); - expect(await values).toEqual([key1, key2]); - }); - }); - - it('observeKeys sees existing and new keys', () => { - waitsForPromise(async () => { - const factory = jasmine.createSpy('factory').andCallFake(key => value); - const cache: Cache = new Cache(factory); - - cache.get(key1); - const values = cache.observeKeys().toArray().toPromise(); - cache.get(key2); - cache.dispose(); - expect(await values).toEqual([key1, key2]); - }); - }); -}); diff --git a/pkg/commons-node/spec/collection-spec.js b/pkg/commons-node/spec/collection-spec.js deleted file mode 100644 index af1e09e0b7..0000000000 --- a/pkg/commons-node/spec/collection-spec.js +++ /dev/null @@ -1,411 +0,0 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the license found in the LICENSE file in - * the root directory of this source tree. - * - * @flow - */ - -import { - arrayRemove, - arrayEqual, - arrayCompact, - arrayFindLastIndex, - mapUnion, - isEmpty, - keyMirror, - setIntersect, - collect, - MultiMap, - objectEntries, - objectFromMap, - concatIterators, - areSetsEqual, - someOfIterable, - findInIterable, - filterIterable, - mapEqual, - mapIterable, -} from '../collection'; - -describe('arrayRemove', () => { - let a: any; - let empty: any; - let single: any; - - beforeEach(() => { - a = ['a', 'b', 'c']; - empty = []; - single = ['x']; - }); - - it('removes an element properly', () => { - arrayRemove(a, 'b'); - expect(a).toEqual(['a', 'c']); - }); - - it('removes the first element properly', () => { - arrayRemove(a, 'a'); - expect(a).toEqual(['b', 'c']); - }); - - it('removes the last element properly', () => { - arrayRemove(a, 'c'); - expect(a).toEqual(['a', 'b']); - }); - - it('does nothing if the element is not found', () => { - arrayRemove(a, 'd'); - expect(a).toEqual(['a', 'b', 'c']); - }); - - it('does nothing to an empty array', () => { - arrayRemove(empty, 'a'); - expect(empty).toEqual([]); - }); - - it('works when there is a single element', () => { - arrayRemove(single, 'x'); - expect(single).toEqual([]); - }); -}); - -describe('arrayEqual', () => { - it('checks boolean elements', () => { - expect(arrayEqual([true, false, true], [true, false, true])).toBe(true); - expect(arrayEqual([true], [false])).toBe(false); - }); - - it('checks number elements', () => { - expect(arrayEqual([1, 2, 3], [1, 2, 3])).toBe(true); - expect(arrayEqual([1, 5, 3], [1, 2, 3])).toBe(false); - }); - - it('checks object elements', () => { - expect(arrayEqual([{}], [{}])).toBe(false); - expect(arrayEqual([{x: 1}, {x: 2}], [{x: 1}, {x: 2}], (a, b) => a.x === b.x)).toBe(true); - }); - - it('works with arrays of different lengths', () => { - expect(arrayEqual([1, 2], [1, 2, 3])).toBe(false); - expect(arrayEqual([1, 2, 3], [1, 2])).toBe(false); - }); -}); - -describe('arrayCompact', () => { - it('filters out null and undefined elements', () => { - expect(arrayCompact([0, false, '', [], null, undefined])).toEqual([0, false, '', []]); - }); -}); - -describe('arrayFindLastIndex', () => { - it('returns the last matching index', () => { - expect(arrayFindLastIndex([1, 1, 2], x => x === 1)).toBe(1); - }); - - it('returns -1 if no match is found', () => { - expect(arrayFindLastIndex([1, 1, 2], x => x === 0)).toBe(-1); - }); -}); - -describe('mapUnion', () => { - it('merges two unique maps', () => { - const map1 = new Map([['key1', 'value1'], ['key2', 'value2']]); - const map2 = new Map([['key3', 'value3'], ['key4', 'value4']]); - const result = mapUnion(map1, map2); - - expect(result.size).toBe(4); - expect(result.get('key1')).toBe('value1'); - expect(result.get('key2')).toBe('value2'); - expect(result.get('key3')).toBe('value3'); - expect(result.get('key4')).toBe('value4'); - }); - - it('overrodes with the values of the latest maps', () => { - const map1 = new Map([['commonKey', 'value1'], ['key2', 'value2']]); - const map2 = new Map([['commonKey', 'value3'], ['key4', 'value4']]); - const result = mapUnion(...[map1, map2]); - - expect(result.size).toBe(3); - expect(result.get('commonKey')).toBe('value3'); - expect(result.get('key2')).toBe('value2'); - expect(result.get('key4')).toBe('value4'); - }); -}); - -describe('isEmpty', () => { - it('correctly identifies empty Objects', () => { - expect(isEmpty({})).toEqual(true); - }); - - it('correctly identifies non-empty Objects', () => { - const proto = {a: 1, b: 2, c: 3}; - const objWithOwnProperties = Object.create(proto, {foo: {value: 'bar'}}); - const objWithoutOwnProperties = Object.create(proto); - - expect(isEmpty({a: 1})).toEqual(false); - expect(isEmpty(objWithOwnProperties)).toEqual(false); - expect(isEmpty(objWithoutOwnProperties)).toEqual(false); - }); -}); - -describe('keyMirror', () => { - it('correctly mirrors objects', () => { - expect(keyMirror({a: null, b: null})).toEqual({a: 'a', b: 'b'}); - }); -}); - -describe('setIntersect', () => { - it('intersects', () => { - const set1 = new Set(['foo', 'bar', 'baz']); - const set2 = new Set(['fool', 'bar', 'bazl']); - const result = setIntersect(set1, set2); - - expect(result.size).toBe(1); - expect(result.has('bar')).toBe(true); - }); -}); - -describe('collect', () => { - it('collects key-value pairs into a Map of arrays', () => { - const pairs = [ - ['neither', 1], - ['neither', 2], - ['fizz', 3], - ['neither', 4], - ['buzz', 5], - ['fizz', 6], - ['neither', 7], - ['neither', 8], - ['fizz', 9], - ]; - const result = collect(pairs); - - expect(result.size).toBe(3); - expect(result.get('fizz')).toEqual([3, 6, 9]); - expect(result.get('buzz')).toEqual([5]); - expect(result.get('neither')).toEqual([1, 2, 4, 7, 8]); - }); -}); - -describe('MultiMap', () => { - let multimap: MultiMap = (null: any); - - beforeEach(() => { - multimap = new MultiMap(); - }); - - afterEach(() => { - // check representation invariants - let size = 0; - for (const [, set] of multimap._map) { - expect(set.size).toBeGreaterThan(0); - size += set.size; - } - expect(multimap.size).toEqual(size); - }); - - it("returns an empty set when a binding doesn't exist", () => { - expect(multimap.get(4)).toEqual(new Set()); - }); - - it('returns itself from add', () => { - expect(multimap.add(1, 2)).toBe(multimap); - }); - - it('properly adds a single binding', () => { - multimap.add(1, 2); - expect(multimap.size).toEqual(1); - expect(multimap.get(1)).toEqual(new Set([2])); - }); - - it('properly adds multiple bindings', () => { - multimap.add(1, 2).add(1, 3).add(10, 11); - expect(multimap.size).toEqual(3); - expect(multimap.get(1)).toEqual(new Set([2, 3])); - expect(multimap.get(10)).toEqual(new Set([11])); - }); - - it('returns false from delete when nothing was deleted', () => { - multimap.add(1, 2); - expect(multimap.delete(1, 3)).toBe(false); - expect(multimap.delete(2, 3)).toBe(false); - }); - - it('properly deletes a single binding', () => { - multimap.add(1, 2).add(1, 3).add(10, 11); - expect(multimap.delete(1, 2)).toBe(true); - expect(multimap.get(1)).toEqual(new Set([3])); - expect(multimap.get(10)).toEqual(new Set([11])); - expect(multimap.size).toEqual(2); - }); - - it('returns false from deleteAll when nothing was deleted', () => { - expect(multimap.deleteAll(5)).toBe(false); - }); - - it('properly deletes all bindings for a given key', () => { - multimap.add(1, 2).add(1, 3); - expect(multimap.deleteAll(1)).toBe(true); - expect(multimap.size).toEqual(0); - expect(multimap.get(1)).toEqual(new Set()); - }); - - it('properly clears', () => { - multimap.add(1, 2).add(1, 3).add(10, 11); - multimap.clear(); - expect(multimap.size).toEqual(0); - expect(multimap.get(1)).toEqual(new Set()); - expect(multimap.get(10)).toEqual(new Set()); - }); - - it('checks membership with has', () => { - multimap.add(1, 2); - expect(multimap.has(5, 6)).toBe(false); - expect(multimap.has(1, 2)).toBe(true); - expect(multimap.has(1, 3)).toBe(false); - }); - - it('checks membership with hasAny', () => { - multimap.add(1, 2); - expect(multimap.hasAny(1)).toBe(true); - expect(multimap.hasAny(2)).toBe(false); - }); -}); - -describe('objectEntries', () => { - it('gets the entries of an object', () => { - expect(objectEntries({a: 1, b: 2})).toEqual([['a', 1], ['b', 2]]); - }); - - it('errors for null', () => { - expect(() => objectEntries((null: any))).toThrow(); - }); - - it('errors for undefined', () => { - expect(() => objectEntries((null: any))).toThrow(); - }); - - it('only includes own properties', () => { - const a = {a: 1}; - const b = {b: 2}; - Object.setPrototypeOf(b, a); - expect(objectEntries(b)).toEqual([['b', 2]]); - }); -}); - -describe('objectFromMap', () => { - it('converts a map to an object', () => { - expect(objectFromMap(new Map([['a', 1], ['b', 2]]))).toEqual({a: 1, b: 2}); - }); -}); - -describe('concatIterators', () => { - it('concatenates different iterable stuff to a single iterator', () => { - expect(Array.from(concatIterators( - new Set([1, 2, 3]), - [4, 5, 6], - new Set([7, 8, 9]).values(), - ))).toEqual([1, 2, 3, 4, 5, 6, 7, 8, 9]); - }); -}); - -describe('areSetsEqual', () => { - it('correctly compares empty sets', () => { - expect(areSetsEqual(new Set(), new Set())).toBe(true); - }); - - it('correctly compares sets with the same properties', () => { - expect(areSetsEqual(new Set(['foo']), new Set(['foo']))).toBe(true); - }); - - it('returns false when properties are not equal', () => { - expect(areSetsEqual(new Set(['foo']), new Set(['bar']))).toBe(false); - }); - - it('returns false when an item exists in one set but not the other', () => { - expect(areSetsEqual(new Set(['foo']), new Set())).toBe(false); - expect(areSetsEqual(new Set(), new Set(['foo']))).toBe(false); - }); -}); - -describe('someOfIterable', () => { - it('lazily returns whether any element of an iterable fulfills a given predicate', () => { - expect(someOfIterable( - new Set([1, 2, 3, 4, 5]), - element => element % 2 === 0, - )).toEqual(true); - expect(someOfIterable( - new Set([1, 2, 3, 4, 5]), - element => element % 5 === 0, - )).toEqual(true); - expect(someOfIterable( - new Set([1, 2, 3, 4, 5]), - element => element % 6 === 0, - )).toEqual(false); - expect(someOfIterable( - [], - element => true, - )).toEqual(false); - }); -}); - -describe('findInIterable', () => { - it('return the first element of an iterable which fulfills a given predicate', () => { - expect(findInIterable( - new Set([1, 2, 3, 4, 5]), - element => element % 2 === 0, - )).toEqual(2); - expect(findInIterable( - new Set([1, 2, 3, 4, 5]), - element => element % 5 === 0, - )).toEqual(5); - expect(findInIterable( - new Set([1, 2, 3, 4, 5]), - element => element % 6 === 0, - )).toEqual(null); - expect(findInIterable( - [], - element => true, - )).toEqual(null); - }); -}); - -describe('filterIterable', () => { - it('returns a (lazy) iterable containing all elements which fulfill the given predicate', () => { - expect(Array.from(filterIterable(new Set([1, 2, 3, 4, 5]), element => element % 2 === 0))) - .toEqual([2, 4]); - expect(Array.from(filterIterable(new Set([1, 2, 3, 4, 5]), element => true))) - .toEqual([1, 2, 3, 4, 5]); - expect(Array.from(filterIterable(new Set([1, 2, 3, 4, 5]), element => false))).toEqual([]); - expect(Array.from(filterIterable([], element => true))).toEqual([]); - }); -}); - -describe('mapEqual', () => { - it('checks primary elements', () => { - expect(mapEqual( - new Map([[1, true], [2, false], [5, true]]), - new Map([[1, true], [2, false], [5, true]]), - )).toBe(true); - expect(mapEqual(new Map([[1, true]]), new Map([[1, false]]))).toBe(false); - expect(mapEqual(new Map([[1, true]]), new Map([]))).toBe(false); - expect(mapEqual(new Map([[1, true]]), new Map([[2, false]]))).toBe(false); - }); - - it('checks object value elements', () => { - expect(mapEqual(new Map([[1, {x: 1}]]), new Map([[1, {x: 1}]]))).toBe(false); - expect(mapEqual(new Map([[1, {x: 1}]]), new Map([[1, {x: 1}]]), (v1, v2) => v1.x === v2.x)) - .toBe(true); - }); -}); - -describe('mapIterable', () => { - it('projects each element of an iterable into a new iterable', () => { - expect(Array.from(mapIterable(new Set(), element => true))).toEqual([]); - expect(Array.from(mapIterable(new Set([1, 2, 3, 4, 5]), element => element * element))) - .toEqual([1, 4, 9, 16, 25]); - }); -}); diff --git a/pkg/commons-node/spec/compareVersions-spec.js b/pkg/commons-node/spec/compareVersions-spec.js deleted file mode 100644 index 954fe9b333..0000000000 --- a/pkg/commons-node/spec/compareVersions-spec.js +++ /dev/null @@ -1,27 +0,0 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the license found in the LICENSE file in - * the root directory of this source tree. - * - * @flow - */ - -import compareVersions from '../compareVersions'; - -describe('compareVersions', () => { - it('compares two versions', () => { - expect(compareVersions('9.2', '10.0')).toBe(-1); - }); - - it('compares versions with an unequal number of parts', () => { - expect(compareVersions('9', '8.9')).toBe(1); - expect(compareVersions('9', '9.1')).toBe(-1); - expect(compareVersions('9', '9.0')).toBe(0); - }); - - it('compares numbers using version numbers and not decimal values', () => { - expect(compareVersions('9.2', '9.10')).toBe(-1); - }); -}); diff --git a/pkg/commons-node/spec/debounce-spec.js b/pkg/commons-node/spec/debounce-spec.js deleted file mode 100644 index 77b2029abd..0000000000 --- a/pkg/commons-node/spec/debounce-spec.js +++ /dev/null @@ -1,62 +0,0 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the license found in the LICENSE file in - * the root directory of this source tree. - * - * @flow - */ - -import invariant from 'assert'; -import debounce from '../debounce'; - -describe('debounce()', () => { - it('only calls function once after time advances', () => { - const timerCallback: any = jasmine.createSpy('timerCallback'); - const debouncedFunc = debounce(timerCallback, 100, false); - - debouncedFunc(); - expect(timerCallback).not.toHaveBeenCalled(); - - advanceClock(101); - expect(timerCallback).toHaveBeenCalled(); - }); - - it('disposes', () => { - const timerCallback: any = jasmine.createSpy('timerCallback'); - const debouncedFunc = debounce(timerCallback, 100, false); - - debouncedFunc(); - expect(timerCallback).not.toHaveBeenCalled(); - - debouncedFunc.dispose(); - - advanceClock(101); - expect(timerCallback).not.toHaveBeenCalled(); - }); - - it('does not swallow flow types', () => { - const func = (a: string): number => 1; - const debounced = debounce(func, 0); - const ret = debounced('bar'); - - // $FlowIgnore: func's first param should be a string. - debounced(1); - - expect(() => { - // $FlowIgnore: debounce's return type is "maybe func's return" type. - (ret: number); - // This is false because we haven't waited for the timer. - invariant(ret != null); - (ret: number); - }).toThrow(); - - debounced.dispose(); - - expect(() => { - // $FlowIgnore: debounced has no "bar" property. - debounced.bar(); - }).toThrow(); - }); -}); diff --git a/pkg/commons-node/spec/event-spec.js b/pkg/commons-node/spec/event-spec.js deleted file mode 100644 index 1bc0ef5aba..0000000000 --- a/pkg/commons-node/spec/event-spec.js +++ /dev/null @@ -1,88 +0,0 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the license found in the LICENSE file in - * the root directory of this source tree. - * - * @flow - */ - -import invariant from 'assert'; -import EventEmitter from 'events'; -import {attachEvent, observableFromSubscribeFunction} from '../event'; - -describe('attachEvent', () => { - describe('the returned disposable', () => { - it("doesn't remove other listeners when disposed multiple times", () => { - const foo = jasmine.createSpy('foo'); - const emitter = new EventEmitter(); - const d1 = attachEvent(emitter, 'event', foo); - attachEvent(emitter, 'event', foo); - d1.dispose(); - d1.dispose(); - emitter.emit('event'); - expect(foo).toHaveBeenCalled(); - }); - }); -}); - -describe('observableFromSubscribeFunction', () => { - let callback: ?((item: number) => mixed); - let disposable: ?IDisposable; - - // The subscribe function will put the given callback and the returned disposable in the variables - // above for inspection. - const subscribeFunction = fn => { - callback = fn; - disposable = {dispose() { callback = null; }}; - spyOn(disposable, 'dispose').andCallThrough(); - return disposable; - }; - - beforeEach(() => { - callback = null; - disposable = null; - }); - - it('should not call the subscription function until the Observable is subscribed to', () => { - const observable = observableFromSubscribeFunction(subscribeFunction); - expect(callback).toBeNull(); - observable.subscribe(() => {}); - expect(callback).not.toBeNull(); - }); - - it('should send events to the observable stream', () => { - waitsForPromise(async () => { - const result = observableFromSubscribeFunction(subscribeFunction) - .take(2) - .toArray() - .toPromise(); - invariant(callback != null); - callback(1); - callback(2); - expect(await result).toEqual([1, 2]); - }); - }); - - it('should properly unsubscribe and resubscribe', () => { - const observable = observableFromSubscribeFunction(subscribeFunction); - let subscription = observable.subscribe(() => {}); - expect(callback).not.toBeNull(); - - invariant(disposable != null); - expect(disposable.dispose).not.toHaveBeenCalled(); - subscription.unsubscribe(); - expect(disposable.dispose).toHaveBeenCalled(); - - expect(callback).toBeNull(); - - subscription = observable.subscribe(() => {}); - - expect(callback).not.toBeNull(); - - expect(disposable.dispose).not.toHaveBeenCalled(); - subscription.unsubscribe(); - expect(disposable.dispose).toHaveBeenCalled(); - }); -}); diff --git a/pkg/commons-node/spec/fixtures/ConfigCache/.test_nuclide_config_file b/pkg/commons-node/spec/fixtures/ConfigCache/.test_nuclide_config_file deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/pkg/commons-node/spec/fixtures/ConfigCache/file b/pkg/commons-node/spec/fixtures/ConfigCache/file deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/pkg/commons-node/spec/fixtures/ConfigCache/testFolder/file b/pkg/commons-node/spec/fixtures/ConfigCache/testFolder/file deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/pkg/commons-node/spec/fixtures/throw.js b/pkg/commons-node/spec/fixtures/throw.js deleted file mode 100644 index 8af0a37923..0000000000 --- a/pkg/commons-node/spec/fixtures/throw.js +++ /dev/null @@ -1,11 +0,0 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the license found in the LICENSE file in - * the root directory of this source tree. - * - * @flow - */ - -throw new Error('Errored!'); diff --git a/pkg/commons-node/spec/fsPromise-spec.js b/pkg/commons-node/spec/fsPromise-spec.js deleted file mode 100644 index 87b0c0b660..0000000000 --- a/pkg/commons-node/spec/fsPromise-spec.js +++ /dev/null @@ -1,123 +0,0 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the license found in the LICENSE file in - * the root directory of this source tree. - * - * @flow - */ - -import nuclideUri from '../nuclideUri'; -import fsPromise from '../fsPromise'; -import {generateFixture} from '../../nuclide-test-helpers'; - -describe('fsPromise test suite', () => { - describe('findNearestFile()', () => { - let dirPath: string = (null: any); - - beforeEach(() => { - waitsForPromise(async () => { - dirPath = await generateFixture('nearest_test', new Map([ - ['.some_file', 'just some file'], - ['nested_dir/.another_file', 'just another file'], - ])); - }); - }); - - it('find the file if given the exact directory', () => { - waitsForPromise(async () => { - const foundPath = await fsPromise.findNearestFile('.some_file', dirPath); - expect(foundPath).toBe(dirPath); - }); - }); - - it('find the file if given a nested directory', () => { - waitsForPromise(async () => { - const foundPath = await fsPromise.findNearestFile( - '.some_file', - nuclideUri.join(dirPath, 'nested_dir'), - ); - expect(foundPath).toBe(dirPath); - }); - }); - - it('does not find the file if not existing', () => { - waitsForPromise(async () => { - const foundPath = await fsPromise.findNearestFile( - 'non-existent.txt', - nuclideUri.join(dirPath, 'nested_dir'), - ); - expect(foundPath).toBe(null); - }); - }); - }); - - describe('findFurthestFile()', () => { - let dirPath: string = (null: any); - - beforeEach(() => { - waitsForPromise(async () => { - dirPath = await generateFixture('furthest_test', new Map([ - ['0/.some_file', 'just a file'], - ['0/1/.some_file', 'just b file'], - // Skip one file to test consecutive vs non-consecutive. - // ['0/1/2', 'just c file'], - ['0/1/2/3/.some_file', 'just d file'], - ['0/1/2/3/4/.some_file', 'just f file'], - ])); - }); - }); - - it('find the file if given the exact directory', () => { - waitsForPromise(async () => { - const expectedPath = nuclideUri.join(dirPath, '0'); - const foundPath = await fsPromise.findFurthestFile('.some_file', expectedPath); - expect(foundPath).toBe(expectedPath); - }); - }); - - it('finds the furthest file if given a nested directory', () => { - waitsForPromise(async () => { - const expectedPath = nuclideUri.join(dirPath, '0'); - const startPath = nuclideUri.join(dirPath, '0/1/2/3/4'); - const foundPath = await fsPromise.findFurthestFile('.some_file', startPath); - expect(foundPath).toBe(expectedPath); - }); - }); - - it('terminates search as soon as file is not found if given the stopOnMissing flag', () => { - waitsForPromise(async () => { - const expectedPath = nuclideUri.join(dirPath, '0/1/2/3'); - const startPath = nuclideUri.join(dirPath, '0/1/2/3/4'); - const foundPath = await fsPromise.findFurthestFile( - '.some_file', - startPath, - true /* stopOnMissing */, - ); - expect(foundPath).toBe(expectedPath); - }); - }); - - it('does not find the file if not existing', () => { - waitsForPromise(async () => { - const startPath = nuclideUri.join(dirPath, '0/1/2/3/4'); - const foundPath = await fsPromise.findFurthestFile('non-existent.txt', startPath); - expect(foundPath).toBe(null); - }); - }); - }); - - describe('getCommonAncestorDirectory', () => { - it('gets the parent directory', () => { - expect(fsPromise.getCommonAncestorDirectory([ - '/foo/bar.txt', - '/foo/baz/lol.txt', - ])).toBe('/foo'); - expect(fsPromise.getCommonAncestorDirectory([ - '/foo/bar/abc/def/abc.txt', - '/foo/bar/lol.txt', - ])).toBe('/foo/bar'); - }); - }); -}); diff --git a/pkg/commons-node/spec/humanizeKeystroke-spec.js b/pkg/commons-node/spec/humanizeKeystroke-spec.js deleted file mode 100644 index de2a730009..0000000000 --- a/pkg/commons-node/spec/humanizeKeystroke-spec.js +++ /dev/null @@ -1,80 +0,0 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the license found in the LICENSE file in - * the root directory of this source tree. - * - * @flow - */ - -import humanizeKeystroke from '../humanizeKeystroke'; - -describe('nuclide-keystroke-label', () => { - // adapted from https://github.com/atom/underscore-plus/blob/master/spec/underscore-plus-spec.coffee - describe('humanizeKeystroke', () => { - it('replaces single keystroke', () => { - expect(humanizeKeystroke('cmd-O', 'darwin')).toEqual('⌘⇧O'); - expect(humanizeKeystroke('cmd-O', 'linux')).toEqual('Cmd+Shift+O'); - - expect(humanizeKeystroke('cmd-shift-up', 'darwin')).toEqual('⌘⇧↑'); - expect(humanizeKeystroke('cmd-shift-up', 'linux')).toEqual('Cmd+Shift+Up'); - - expect(humanizeKeystroke('cmd-option-down', 'darwin')).toEqual('⌘⌥↓'); - expect(humanizeKeystroke('cmd-option-down', 'linux')).toEqual('Cmd+Alt+Down'); - - expect(humanizeKeystroke('cmd-option-left', 'darwin')).toEqual('⌘⌥←'); - expect(humanizeKeystroke('cmd-option-left', 'linux')).toEqual('Cmd+Alt+Left'); - - expect(humanizeKeystroke('cmd-option-right', 'darwin')).toEqual('⌘⌥→'); - expect(humanizeKeystroke('cmd-option-right', 'linux')).toEqual('Cmd+Alt+Right'); - - expect(humanizeKeystroke('cmd-o', 'darwin')).toEqual('⌘O'); - expect(humanizeKeystroke('cmd-o', 'linux')).toEqual('Cmd+O'); - - expect(humanizeKeystroke('ctrl-2', 'darwin')).toEqual('⌃2'); - expect(humanizeKeystroke('ctrl-2', 'linux')).toEqual('Ctrl+2'); - - expect(humanizeKeystroke('cmd-space', 'darwin')).toEqual('⌘space'); - expect(humanizeKeystroke('cmd-space', 'linux')).toEqual('Cmd+Space'); - - expect(humanizeKeystroke('cmd-|', 'darwin')).toEqual('⌘⇧\\'); - expect(humanizeKeystroke('cmd-|', 'linux')).toEqual('Cmd+Shift+\\'); - - expect(humanizeKeystroke('cmd-}', 'darwin')).toEqual('⌘⇧]'); - expect(humanizeKeystroke('cmd-}', 'linux')).toEqual('Cmd+Shift+]'); - - expect(humanizeKeystroke('cmd--', 'darwin')).toEqual('⌘-'); - expect(humanizeKeystroke('cmd--', 'linux')).toEqual('Cmd+-'); - }); - - it('correctly replaces keystrokes with shift and capital letter', () => { - expect(humanizeKeystroke('cmd-shift-P', 'darwin')).toEqual('⌘⇧P'); - expect(humanizeKeystroke('cmd-shift-P', 'linux')).toEqual('Cmd+Shift+P'); - }); - - it('replaces multiple keystrokes', () => { - expect(humanizeKeystroke('cmd-O cmd-n', 'darwin')).toEqual('⌘⇧O ⌘N'); - expect(humanizeKeystroke('cmd-O cmd-n', 'linux')).toEqual('Cmd+Shift+O Cmd+N'); - - expect(humanizeKeystroke('cmd-shift-- cmd-n', 'darwin')).toEqual('⌘⇧- ⌘N'); - expect(humanizeKeystroke('cmd-shift-- cmd-n', 'linux')).toEqual('Cmd+Shift+- Cmd+N'); - - expect(humanizeKeystroke('cmd-k right', 'darwin')).toEqual('⌘K →'); - expect(humanizeKeystroke('cmd-k right', 'linux')).toEqual('Cmd+K Right'); - }); - - it('formats function keys', () => { - expect(humanizeKeystroke('cmd-f2', 'darwin')).toEqual('⌘F2'); - expect(humanizeKeystroke('cmd-f2', 'linux')).toEqual('Cmd+F2'); - }); - - it('handles junk input', () => { - // $FlowFixMe: Deliberately testing invalid input. - expect(humanizeKeystroke()).toEqual(undefined); - // $FlowFixMe: Deliberately testing invalid input. - expect(humanizeKeystroke(null)).toEqual(null); - expect(humanizeKeystroke('')).toEqual(''); - }); - }); -}); diff --git a/pkg/commons-node/spec/memoizeUntilChanged-spec.js b/pkg/commons-node/spec/memoizeUntilChanged-spec.js deleted file mode 100644 index 465f6b1a0c..0000000000 --- a/pkg/commons-node/spec/memoizeUntilChanged-spec.js +++ /dev/null @@ -1,43 +0,0 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the license found in the LICENSE file in - * the root directory of this source tree. - * - * @flow - */ - -import memoizeUntilChanged from '../memoizeUntilChanged'; - -const sum = (a, b) => a + b; - -describe('memoizeUntilChanged', () => { - it('memoizes', () => { - const spy = jasmine.createSpy().andCallFake(sum); - const f = memoizeUntilChanged(spy); - f(1, 2); - const result = f(1, 2); - expect(result).toBe(3); - expect(spy.callCount).toBe(1); - }); - - it('resets when args change', () => { - const spy = jasmine.createSpy().andCallFake(sum); - const f = memoizeUntilChanged(spy); - f(1, 2); - const result = f(1, 3); - expect(result).toBe(4); - expect(spy.callCount).toBe(2); - }); - - it('preserves context', () => { - let that; - const obj = {}; - const f = memoizeUntilChanged(function f() { - that = this; - }); - f.call(obj); - expect(that).toBe(obj); - }); -}); diff --git a/pkg/commons-node/spec/nice-spec.js b/pkg/commons-node/spec/nice-spec.js deleted file mode 100644 index 97260e7e78..0000000000 --- a/pkg/commons-node/spec/nice-spec.js +++ /dev/null @@ -1,133 +0,0 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the license found in the LICENSE file in - * the root directory of this source tree. - * - * @flow - */ - -import typeof { - niceSafeSpawn as niceSafeSpawnType, - niceCheckOutput as niceCheckOutputType, - niceAsyncExecute as niceAsyncExecuteType, -} from '../nice'; - -import type {AsyncExecuteReturn} from '../process'; - -import {uncachedRequire} from '../../nuclide-test-helpers'; - -describe('nice', () => { - let niceSafeSpawn: niceSafeSpawnType = (null: any); - let niceCheckOutput: niceCheckOutputType = (null: any); - let niceAsyncExecute: niceAsyncExecuteType = (null: any); - - let whichSpy: JasmineSpy = (null: any); - let safeSpawnSpy: JasmineSpy = (null: any); - let checkOutputSpy: JasmineSpy = (null: any); - let asyncExecuteSpy: JasmineSpy = (null: any); - let shouldFindNiceCommand: boolean = (null: any); - let shouldFindIoniceCommand: boolean = (null: any); - // All we need here is a unique value to make sure that `nice` returns whatever `safeSpawn` - // returns - const fakeSafeSpawnReturn: child_process$ChildProcess = ({}: any); - const fakeCheckOutputReturn: AsyncExecuteReturn = ({}: any); - const fakeAsyncExecuteReturn: AsyncExecuteReturn = ({}: any); - - beforeEach(() => { - shouldFindNiceCommand = true; - shouldFindIoniceCommand = true; - whichSpy = spyOn(require('../which'), 'default').andCallFake(command => { - if ( - (shouldFindNiceCommand && command === 'nice') || - (shouldFindIoniceCommand && command === 'ionice') - ) { - return command; - } else { - return null; - } - }); - safeSpawnSpy = spyOn(require('../process'), 'safeSpawn').andReturn(fakeSafeSpawnReturn); - checkOutputSpy = spyOn(require('../process'), 'checkOutput').andReturn(fakeCheckOutputReturn); - asyncExecuteSpy = - spyOn(require('../process'), 'asyncExecute').andReturn(fakeAsyncExecuteReturn); - ({niceSafeSpawn, niceAsyncExecute, niceCheckOutput} = - (uncachedRequire(require, '../nice'): any)); - }); - - it('should spawn `nice` and return whatever safeSpawn returns', () => { - waitsForPromise(async () => { - const execOptions = {}; - const result = await niceSafeSpawn('echo', ['hi'], execOptions); - expect(safeSpawnSpy).toHaveBeenCalledWith( - 'ionice', ['-n', '7', 'nice', 'echo', 'hi'], execOptions, - ); - expect(result).toBe(fakeSafeSpawnReturn); - }); - }); - - it('should spawn the command normally if nice and ionice cannot be found', () => { - waitsForPromise(async () => { - shouldFindNiceCommand = false; - shouldFindIoniceCommand = false; - const execOptions = {}; - const result = await niceSafeSpawn('echo', ['hi'], execOptions); - expect(safeSpawnSpy).toHaveBeenCalledWith('echo', ['hi'], execOptions); - expect(result).toBe(fakeSafeSpawnReturn); - }); - }); - - it('should spawn with only nice if ionice cannot be found', () => { - waitsForPromise(async () => { - shouldFindIoniceCommand = false; - const execOptions = {}; - const result = await niceSafeSpawn('echo', ['hi'], execOptions); - expect(safeSpawnSpy).toHaveBeenCalledWith('nice', ['echo', 'hi'], execOptions); - expect(result).toBe(fakeSafeSpawnReturn); - }); - }); - - it('should spawn with only ionice if nice cannot be found', () => { - waitsForPromise(async () => { - // I don't know when we would have ionice but not nice, but we may as well support this case. - shouldFindNiceCommand = false; - const execOptions = {}; - const result = await niceSafeSpawn('echo', ['hi'], execOptions); - expect(safeSpawnSpy).toHaveBeenCalledWith('ionice', ['-n', '7', 'echo', 'hi'], execOptions); - expect(result).toBe(fakeSafeSpawnReturn); - }); - }); - - it('should call which only once per command and cache the result', () => { - waitsForPromise(async () => { - await niceSafeSpawn('echo', []); - await niceSafeSpawn('echo', []); - expect(whichSpy).toHaveBeenCalledWith('nice'); - expect(whichSpy).toHaveBeenCalledWith('ionice'); - expect(whichSpy.callCount).toBe(2); - }); - }); - - it('should call checkOutput when the niceCheckOutput variant is used', () => { - waitsForPromise(async () => { - const execOptions = {}; - const result = await niceCheckOutput('echo', ['hi'], execOptions); - expect(checkOutputSpy).toHaveBeenCalledWith( - 'ionice', ['-n', '7', 'nice', 'echo', 'hi'], execOptions, - ); - expect(result).toBe(fakeCheckOutputReturn); - }); - }); - - it('should call asyncExecute when the niceAsyncExecute variant is used', () => { - waitsForPromise(async () => { - const execOptions = {}; - const result = await niceAsyncExecute('echo', ['hi'], execOptions); - expect(asyncExecuteSpy).toHaveBeenCalledWith( - 'ionice', ['-n', '7', 'nice', 'echo', 'hi'], execOptions, - ); - expect(result).toBe(fakeAsyncExecuteReturn); - }); - }); -}); diff --git a/pkg/commons-node/spec/nuclideUri-spec.js b/pkg/commons-node/spec/nuclideUri-spec.js deleted file mode 100644 index e9a1a4231f..0000000000 --- a/pkg/commons-node/spec/nuclideUri-spec.js +++ /dev/null @@ -1,408 +0,0 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the license found in the LICENSE file in - * the root directory of this source tree. - * - * @flow - */ - -import nuclideUri, {__TEST__} from '../nuclideUri'; -// eslint-disable-next-line nuclide-internal/prefer-nuclide-uri -import path from 'path'; - -describe('nuclide-uri', () => { - const localUri = '/usr/local/file'; - const badRemoteUriNoPath = 'nuclide://fb.com'; - const atomUri = 'atom://bla/bla'; - const remoteUri = nuclideUri.createRemoteUri('fb.com', '/usr/local'); - const remoteUriWithSpaces = nuclideUri.createRemoteUri('fb.com', '/a b/c d'); - const remoteUriWithHashes = nuclideUri.createRemoteUri('fb.co.uk', '/ab/#c.d #'); - - it('isRemote', () => { - expect(nuclideUri.isRemote('/')).toBe(false); - expect(nuclideUri.isRemote(remoteUri)).toBe(true); - expect(nuclideUri.isRemote(atomUri)).toBe(false); - }); - - it('isLocal', () => { - expect(nuclideUri.isLocal('/')).toBe(true); - expect(nuclideUri.isLocal(remoteUri)).toBe(false); - expect(nuclideUri.isLocal('C:\\abc')).toBe(true); - expect(nuclideUri.isLocal(atomUri)).toBe(false); - }); - - it('createRemoteUri', () => { - expect(remoteUri).toBe('nuclide://fb.com/usr/local'); - expect(remoteUriWithSpaces).toBe('nuclide://fb.com/a b/c d'); - }); - - it('join', () => { - expect(nuclideUri.join.bind(null, badRemoteUriNoPath, '../foo')).toThrow(); - expect(nuclideUri.join('/usr/local', 'bin')).toBe('/usr/local/bin'); - expect(nuclideUri.join(remoteUri, 'bin')).toBe('nuclide://fb.com/usr/local/bin'); - expect(nuclideUri.join('/usr/local', '..')).toBe('/usr'); - expect(nuclideUri.join(remoteUri, '..')).toBe('nuclide://fb.com/usr'); - expect(() => nuclideUri.join(atomUri)).toThrow(); - }); - - describe('parsing remote', () => { - it('handles simple paths', () => { - expect(nuclideUri.getHostname(remoteUri)).toBe('fb.com'); - expect(nuclideUri.getPath(remoteUri)).toBe('/usr/local'); - }); - - it('does not encode space characters', () => { - expect(nuclideUri.getHostname(remoteUriWithSpaces)).toBe('fb.com'); - expect(nuclideUri.getPath(remoteUriWithSpaces)).toBe('/a b/c d'); - }); - - it('treats hash symbols as literals, part of the path', () => { - const parsedUri = nuclideUri.parse(remoteUriWithHashes); - expect(parsedUri.hostname).toBe('fb.co.uk'); - expect(parsedUri.path).toBe('/ab/#c.d #'); - }); - - it('throws when given an Atom URI', () => { - expect(() => nuclideUri.getHostname(atomUri)).toThrow(); - expect(() => nuclideUri.getPath(atomUri)).toThrow(); - expect(() => nuclideUri.parse(atomUri)).toThrow(); - }); - }); - - it('parsing local', () => { - expect(() => nuclideUri.getHostname(localUri)).toThrow(); - expect(nuclideUri.getPath(localUri)).toBe(localUri); - expect(() => nuclideUri.parseRemoteUri(localUri)).toThrow(); - }); - - it('basename', () => { - expect(nuclideUri.basename('/')).toBe(''); - expect(nuclideUri.basename('/abc')).toBe('abc'); - expect(nuclideUri.basename('/abc/')).toBe('abc'); - expect(nuclideUri.basename('/abc/def')).toBe('def'); - expect(nuclideUri.basename('/abc/def/')).toBe('def'); - - expect(nuclideUri.basename('nuclide://host/')).toBe(''); - expect(nuclideUri.basename('nuclide://host/abc')).toBe('abc'); - expect(nuclideUri.basename('nuclide://host/abc/')).toBe('abc'); - expect(nuclideUri.basename('nuclide://host/abc/def')).toBe('def'); - expect(nuclideUri.basename('nuclide://host/abc/def/')).toBe('def'); - expect(nuclideUri.basename('nuclide://host/a c/d f')).toBe('d f'); - - expect(nuclideUri.basename('C:\\')).toBe(''); - expect(nuclideUri.basename('C:\\abc')).toBe('abc'); - expect(nuclideUri.basename('C:\\abc\\')).toBe('abc'); - expect(nuclideUri.basename('C:\\abc\\def')).toBe('def'); - expect(nuclideUri.basename('C:\\abc\\def\\')).toBe('def'); - expect(nuclideUri.basename('\\abc\\def')).toBe('def'); - expect(nuclideUri.basename('\\abc\\def\\')).toBe('def'); - - expect(() => nuclideUri.basename(atomUri)).toThrow(); - }); - - it('dirname', () => { - expect(nuclideUri.dirname('/')).toBe('/'); - expect(nuclideUri.dirname('/abc')).toBe('/'); - expect(nuclideUri.dirname('/abc/')).toBe('/'); - expect(nuclideUri.dirname('/abc/def')).toBe('/abc'); - expect(nuclideUri.dirname('/abc/def/')).toBe('/abc'); - - expect(nuclideUri.dirname('nuclide://host/')).toBe('nuclide://host/'); - expect(nuclideUri.dirname('nuclide://host/abc')).toBe('nuclide://host/'); - expect(nuclideUri.dirname('nuclide://host/abc/')).toBe('nuclide://host/'); - expect(nuclideUri.dirname('nuclide://host/abc/def')).toBe('nuclide://host/abc'); - expect(nuclideUri.dirname('nuclide://host/abc/def/')).toBe('nuclide://host/abc'); - expect(nuclideUri.dirname('nuclide://host/a c/d f')).toBe('nuclide://host/a c'); - - expect(nuclideUri.dirname('C:\\')).toBe('C:\\'); - expect(nuclideUri.dirname('C:\\abc')).toBe('C:\\'); - expect(nuclideUri.dirname('C:\\abc\\')).toBe('C:\\'); - expect(nuclideUri.dirname('C:\\abc\\def')).toBe('C:\\abc'); - expect(nuclideUri.dirname('C:\\abc\\def\\')).toBe('C:\\abc'); - expect(nuclideUri.dirname('\\abc\\def')).toBe('\\abc'); - expect(nuclideUri.dirname('\\abc\\def\\')).toBe('\\abc'); - - expect(() => nuclideUri.dirname(atomUri)).toThrow(); - }); - - it('extname', () => { - expect(nuclideUri.extname('/abc')).toBe(''); - expect(nuclideUri.extname('/abc.')).toBe('.'); - expect(nuclideUri.extname('/abc.txt')).toBe('.txt'); - expect(nuclideUri.extname('/abc/def.html')).toBe('.html'); - expect(nuclideUri.extname('/abc/def/')).toBe(''); - expect(nuclideUri.extname('/abc/def.dir/')).toBe('.dir'); - - expect(nuclideUri.extname('nuclide://host/')).toBe(''); - expect(nuclideUri.extname('nuclide://host/abc')).toBe(''); - expect(nuclideUri.extname('nuclide://host/abc.txt')).toBe('.txt'); - expect(nuclideUri.extname('nuclide://host/abc.')).toBe('.'); - expect(nuclideUri.extname('nuclide://host/abc/')).toBe(''); - expect(nuclideUri.extname('nuclide://host/abc/def')).toBe(''); - expect(nuclideUri.extname('nuclide://host/abc/def.js')).toBe('.js'); - - expect(nuclideUri.extname('C:\\')).toBe(''); - expect(nuclideUri.extname('C:\\abc')).toBe(''); - expect(nuclideUri.extname('C:\\abc\\')).toBe(''); - expect(nuclideUri.extname('C:\\abc.')).toBe('.'); - expect(nuclideUri.extname('C:\\abc.js')).toBe('.js'); - expect(nuclideUri.extname('C:\\abc\\def')).toBe(''); - expect(nuclideUri.extname('C:\\abc\\def\\')).toBe(''); - expect(nuclideUri.extname('C:\\abc\\def.')).toBe('.'); - expect(nuclideUri.extname('C:\\abc\\def.html')).toBe('.html'); - expect(nuclideUri.extname('\\abc\\def')).toBe(''); - expect(nuclideUri.extname('\\abc\\def.dir\\')).toBe('.dir'); - expect(nuclideUri.extname('\\abc\\def.')).toBe('.'); - expect(nuclideUri.extname('\\abc\\def.xml')).toBe('.xml'); - - expect(() => nuclideUri.extname(atomUri)).toThrow(); - }); - - it('getParent', () => { - expect(nuclideUri.getParent(localUri)).toBe('/usr/local'); - expect(nuclideUri.getParent(remoteUri)).toBe('nuclide://fb.com/usr'); - expect(() => nuclideUri.getParent(atomUri)).toThrow(); - }); - - it('contains', () => { - expect(nuclideUri.contains('/usr/local', localUri)).toBe(true); - expect(nuclideUri.contains('nuclide://fb.com/usr', remoteUri)).toBe(true); - expect(nuclideUri.contains('/foo/bar/', '/foo/bar/abc.txt')).toBe(true); - expect(nuclideUri.contains('/foo/bar', '/foo/bar/')).toBe(true); - expect(nuclideUri.contains('/foo/bar/', '/foo/bar/')).toBe(true); - expect(nuclideUri.contains('/foo/bar/', '/foo/bar')).toBe(true); - expect(() => nuclideUri.contains(atomUri, '/foo/bar')).toThrow(); - expect(() => nuclideUri.contains('/foo/bar', atomUri)).toThrow(); - }); - - it('collapse', () => { - expect(nuclideUri.collapse(['/a', '/b'])).toEqual(['/a', '/b']); - expect(nuclideUri.collapse(['/a/b/c/d', '/a', '/a/b'])).toEqual(['/a']); - expect(nuclideUri.collapse(['/a/c', '/a/c/d', '/a/b', '/a/b/c/d/e'])) - .toEqual(['/a/c', '/a/b']); - expect(nuclideUri.collapse(['/a/be', '/a/b'])).toEqual(['/a/be', '/a/b']); - expect(nuclideUri.collapse([ - 'nuclide://fb.com/usr/local', - 'nuclide://fb.com/usr/local/test', - 'nuclide://facebook.com/usr/local/test', - ])).toEqual([ - 'nuclide://fb.com/usr/local', - 'nuclide://facebook.com/usr/local/test', - ]); - }); - - it('normalize', () => { - expect(nuclideUri.normalize(localUri)).toBe(localUri); - expect(nuclideUri.normalize(remoteUri)).toBe(remoteUri); - expect(nuclideUri.normalize.bind(null, badRemoteUriNoPath)).toThrow(); - expect(nuclideUri.normalize('/usr/local/..')).toBe('/usr'); - expect(nuclideUri.normalize('nuclide://fb.com/usr/local/..')).toBe('nuclide://fb.com/usr'); - expect(nuclideUri.normalize('/a b/c d/..')).toBe('/a b'); - expect(() => nuclideUri.normalize(atomUri)).toThrow(); - }); - - it('relative', () => { - expect(() => nuclideUri.relative(localUri, remoteUri)).toThrow(); - expect(nuclideUri.relative(nuclideUri.dirname(remoteUri), remoteUri)).toBe('local'); - expect(nuclideUri.relative(remoteUri, nuclideUri.dirname(remoteUri))).toBe('..'); - expect(nuclideUri.relative(nuclideUri.dirname(remoteUriWithSpaces), remoteUriWithSpaces)) - .toBe('c d'); - expect(nuclideUri.relative(remoteUriWithSpaces, nuclideUri.dirname(remoteUriWithSpaces))) - .toBe('..'); - expect(nuclideUri.relative(nuclideUri.dirname(localUri), localUri)).toBe('file'); - expect(nuclideUri.relative(localUri, nuclideUri.dirname(localUri))).toBe('..'); - expect(() => nuclideUri.relative(atomUri, 'foo')).toThrow(); - }); - - it('nuclideUriToDisplayString', () => { - expect(nuclideUri.nuclideUriToDisplayString(localUri)).toBe(localUri); - expect(nuclideUri.nuclideUriToDisplayString(remoteUri)).toBe('fb.com:/usr/local'); - expect(() => nuclideUri.nuclideUriToDisplayString(atomUri)).toThrow(); - }); - - describe('isRoot', () => { - it('plain posix root', () => expect(nuclideUri.isRoot('/')).toBe(true)); - it('double root', () => expect(nuclideUri.isRoot('//')).toBe(false)); - it('/abc', () => expect(nuclideUri.isRoot('/abc')).toBe(false)); - it('abc', () => expect(nuclideUri.isRoot('abc')).toBe(false)); - it('abc/def', () => expect(nuclideUri.isRoot('abc/def')).toBe(false)); - it('remote root', () => expect(nuclideUri.isRoot('nuclide://host/')).toBe(true)); - it('remote root with port', () => expect(nuclideUri.isRoot('nuclide://host/')).toBe(true)); - it('remote non-root', () => expect(nuclideUri.isRoot('nuclide://host/abc')).toBe(false)); - it('remote non-root no port', () => { - expect(nuclideUri.isRoot('nuclide://host/abc')).toBe(false); - }); - it('win diskless root', () => expect(nuclideUri.isRoot('\\')).toBe(true)); - it('win diskless double root', () => expect(nuclideUri.isRoot('\\\\')).toBe(false)); - it('win diskless non-root', () => expect(nuclideUri.isRoot('\\abc')).toBe(false)); - it('win diskful root', () => expect(nuclideUri.isRoot('C:\\')).toBe(true)); - it('win diskful double root', () => expect(nuclideUri.isRoot('C:\\\\')).toBe(false)); - it('win diskful non-root', () => expect(nuclideUri.isRoot('C:\\abc')).toBe(false)); - - it('win relative', () => expect(nuclideUri.isRoot('abc\\def')).toBe(false)); - - it('throws on Atom URIs', () => expect(() => nuclideUri.basename(atomUri)).toThrow()); - }); - - it('adds a proper suffix when needed', () => { - expect(nuclideUri.ensureTrailingSeparator('/')).toBe('/'); - expect(nuclideUri.ensureTrailingSeparator('/abc')).toBe('/abc/'); - expect(nuclideUri.ensureTrailingSeparator('/abc/')).toBe('/abc/'); - expect(nuclideUri.ensureTrailingSeparator('/abc/def')).toBe('/abc/def/'); - expect(nuclideUri.ensureTrailingSeparator('/abc/def/')).toBe('/abc/def/'); - expect(nuclideUri.ensureTrailingSeparator('nuclide://host')).toBe('nuclide://host/'); - expect(nuclideUri.ensureTrailingSeparator('nuclide://host/')).toBe('nuclide://host/'); - expect(nuclideUri.ensureTrailingSeparator('nuclide://host/abc')).toBe('nuclide://host/abc/'); - expect(nuclideUri.ensureTrailingSeparator('nuclide://host/abc/def')) - .toBe('nuclide://host/abc/def/'); - expect(nuclideUri.ensureTrailingSeparator('nuclide://host/abc/def/')) - .toBe('nuclide://host/abc/def/'); - expect(nuclideUri.ensureTrailingSeparator('C:\\')).toBe('C:\\'); - expect(nuclideUri.ensureTrailingSeparator('C:\\abc')).toBe('C:\\abc\\'); - expect(nuclideUri.ensureTrailingSeparator('C:\\abc\\')).toBe('C:\\abc\\'); - expect(nuclideUri.ensureTrailingSeparator('C:\\abc\\def')).toBe('C:\\abc\\def\\'); - expect(nuclideUri.ensureTrailingSeparator('C:\\abc\\def\\')).toBe('C:\\abc\\def\\'); - expect(nuclideUri.ensureTrailingSeparator('\\abc\\def')).toBe('\\abc\\def\\'); - expect(nuclideUri.ensureTrailingSeparator('\\abc\\def\\')).toBe('\\abc\\def\\'); - expect(() => nuclideUri.ensureTrailingSeparator(atomUri)).toThrow(); - }); - - it('properly removes suffix when needed', () => { - expect(nuclideUri.trimTrailingSeparator('/')).toBe('/'); - expect(nuclideUri.trimTrailingSeparator('//')).toBe('/'); - expect(nuclideUri.trimTrailingSeparator('/abc')).toBe('/abc'); - expect(nuclideUri.trimTrailingSeparator('/abc/')).toBe('/abc'); - expect(nuclideUri.trimTrailingSeparator('/abc/def')).toBe('/abc/def'); - expect(nuclideUri.trimTrailingSeparator('/abc/def/')).toBe('/abc/def'); - expect(nuclideUri.trimTrailingSeparator('nuclide://host/')).toBe('nuclide://host/'); - expect(nuclideUri.trimTrailingSeparator('nuclide://host//')).toBe('nuclide://host/'); - expect(nuclideUri.trimTrailingSeparator('nuclide://host/')).toBe('nuclide://host/'); - expect(nuclideUri.trimTrailingSeparator('nuclide://host//')).toBe('nuclide://host/'); - expect(nuclideUri.trimTrailingSeparator('nuclide://host/abc')).toBe('nuclide://host/abc'); - expect(nuclideUri.trimTrailingSeparator('nuclide://host/abc/')).toBe('nuclide://host/abc'); - expect(nuclideUri.trimTrailingSeparator('nuclide://host/abc/def')) - .toBe('nuclide://host/abc/def'); - expect(nuclideUri.trimTrailingSeparator('nuclide://host/abc/def/')) - .toBe('nuclide://host/abc/def'); - expect(nuclideUri.trimTrailingSeparator('C:\\')).toBe('C:\\'); - expect(nuclideUri.trimTrailingSeparator('C:\\\\')).toBe('C:\\'); - expect(nuclideUri.trimTrailingSeparator('C:\\abc')).toBe('C:\\abc'); - expect(nuclideUri.trimTrailingSeparator('C:\\abc\\')).toBe('C:\\abc'); - expect(nuclideUri.trimTrailingSeparator('C:\\abc\\def')).toBe('C:\\abc\\def'); - expect(nuclideUri.trimTrailingSeparator('C:\\abc\\def\\')).toBe('C:\\abc\\def'); - expect(nuclideUri.trimTrailingSeparator('\\')).toBe('\\'); - expect(nuclideUri.trimTrailingSeparator('\\\\')).toBe('\\'); - expect(nuclideUri.trimTrailingSeparator('\\abc\\def')).toBe('\\abc\\def'); - expect(nuclideUri.trimTrailingSeparator('\\abc\\def\\')).toBe('\\abc\\def'); - expect(() => nuclideUri.trimTrailingSeparator(atomUri)).toThrow(); - }); - - it('isAbsolute', () => { - expect(nuclideUri.isAbsolute('/abc')).toBe(true); - expect(nuclideUri.isAbsolute('/abc/def')).toBe(true); - expect(nuclideUri.isAbsolute('nuclide://host/')).toBe(true); - expect(nuclideUri.isAbsolute('nuclide://host/abc')).toBe(true); - expect(nuclideUri.isAbsolute('nuclide://host/abc/def')).toBe(true); - - expect(nuclideUri.isAbsolute('C:\\abc')).toBe(true); - expect(nuclideUri.isAbsolute('C:\\abc\\def')).toBe(true); - expect(nuclideUri.isAbsolute('\\abc')).toBe(true); - expect(nuclideUri.isAbsolute('\\abc\\def')).toBe(true); - - expect(nuclideUri.isAbsolute('abc')).toBe(false); - expect(nuclideUri.isAbsolute('abc/def')).toBe(false); - - expect(nuclideUri.isAbsolute('abc\\def')).toBe(false); - expect(() => nuclideUri.isAbsolute(atomUri)).toThrow(); - }); - - - it('resolve', () => { - expect(nuclideUri.resolve('/abc')).toBe('/abc'); - expect(nuclideUri.resolve('/abc', '..')).toBe('/'); - expect(nuclideUri.resolve('/abc', '..', '..')).toBe('/'); - expect(nuclideUri.resolve('/abc', '../..')).toBe('/'); - - expect(nuclideUri.resolve('/abc/def')).toBe('/abc/def'); - expect(nuclideUri.resolve('/abc/def', 'ghi')).toBe('/abc/def/ghi'); - expect(nuclideUri.resolve('/abc/def', '..', 'ghi')).toBe('/abc/ghi'); - expect(nuclideUri.resolve('/abc/def', '../ghi')).toBe('/abc/ghi'); - expect(nuclideUri.resolve('/abc/def', '/ghi')).toBe('/ghi'); - - expect(nuclideUri.resolve('nuclide://host/')).toBe('nuclide://host/'); - expect(nuclideUri.resolve('nuclide://host/', '..')).toBe('nuclide://host/'); - expect(nuclideUri.resolve('nuclide://host/abc')).toBe('nuclide://host/abc'); - expect(nuclideUri.resolve('nuclide://host/abc', '..')).toBe('nuclide://host/'); - expect(nuclideUri.resolve('nuclide://host/abc', '..', '..')).toBe('nuclide://host/'); - expect(nuclideUri.resolve('nuclide://host/abc', '../..')).toBe('nuclide://host/'); - expect(nuclideUri.resolve('nuclide://host/abc/def', 'ghi')) - .toBe('nuclide://host/abc/def/ghi'); - expect(nuclideUri.resolve('nuclide://host/abc/def', '../ghi')) - .toBe('nuclide://host/abc/ghi'); - expect(nuclideUri.resolve('nuclide://host/abc/def', '..', 'ghi')) - .toBe('nuclide://host/abc/ghi'); - expect(nuclideUri.resolve('nuclide://host/abc/def', '/ghi')).toBe('nuclide://host/ghi'); - - expect(nuclideUri.resolve('C:\\abc')).toBe('C:\\abc'); - expect(nuclideUri.resolve('C:\\abc', '..')).toBe('C:\\'); - expect(nuclideUri.resolve('C:\\abc', '..', '..')).toBe('C:\\'); - expect(nuclideUri.resolve('C:\\abc', '..\\..')).toBe('C:\\'); - expect(nuclideUri.resolve('C:\\abc', 'def')).toBe('C:\\abc\\def'); - expect(nuclideUri.resolve('C:\\abc', '..\\def')).toBe('C:\\def'); - expect(nuclideUri.resolve('C:\\abc', '..', 'def')).toBe('C:\\def'); - - expect(nuclideUri.resolve('\\abc', 'def')).toBe('\\abc\\def'); - expect(nuclideUri.resolve('\\abc', '..\\def')).toBe('\\def'); - expect(nuclideUri.resolve('\\abc', '..', 'def')).toBe('\\def'); - expect(() => nuclideUri.resolve(atomUri, '..')).toThrow(); - }); - - describe('expandHomeDir()', () => { - it('expands ~ to HOME', () => { - expect(nuclideUri.expandHomeDir('~')).toBe(process.env.HOME); - }); - - it('expands ~/ to HOME', () => { - const HOME = process.env.HOME; - expect(HOME).not.toBeNull(); - expect(nuclideUri.expandHomeDir('~/abc')).toBe(path.posix.join(HOME, 'abc')); - }); - - it('keeps ~def to ~def', () => { - expect(nuclideUri.expandHomeDir('~def')).toBe('~def'); - }); - - it('throws on Atom URIs', () => { - expect(() => nuclideUri.expandHomeDir(atomUri)).toThrow(); - }); - }); - - it('detects Windows and Posix paths properly', () => { - expect(__TEST__._pathModuleFor('/')).toEqual(path.posix); - expect(__TEST__._pathModuleFor('/abc')).toEqual(path.posix); - expect(__TEST__._pathModuleFor('/abc/def')).toEqual(path.posix); - expect(__TEST__._pathModuleFor('/abc.txt')).toEqual(path.posix); - expect(__TEST__._pathModuleFor('nuclide://host')).toEqual(path.posix); - expect(__TEST__._pathModuleFor('nuclide://host/')).toEqual(path.posix); - expect(__TEST__._pathModuleFor('nuclide://host/abc')).toEqual(path.posix); - expect(__TEST__._pathModuleFor('nuclide://host/abc/def')).toEqual(path.posix); - expect(__TEST__._pathModuleFor('nuclide://host/abc/def.txt')).toEqual(path.posix); - expect(__TEST__._pathModuleFor('C:\\')).toEqual(path.win32); - expect(__TEST__._pathModuleFor('C:\\abc')).toEqual(path.win32); - expect(__TEST__._pathModuleFor('C:\\abc\\def')).toEqual(path.win32); - expect(__TEST__._pathModuleFor('C:\\abc\\def.txt')).toEqual(path.win32); - expect(__TEST__._pathModuleFor('D:\\abc\\aaa bbb')).toEqual(path.win32); - expect(__TEST__._pathModuleFor('\\abc\\def')).toEqual(path.win32); - - // Default to Posix - expect(__TEST__._pathModuleFor('abcdef')).toEqual(path.posix); - }); - - it('properly handles backslash-containing remote URIs', () => { - expect(nuclideUri.getPath('nuclide://host/aaa\\bbb.txt')).toBe('/aaa\\bbb.txt'); - expect(nuclideUri.getPath('nuclide://host/dir/aaa\\bbb.txt')).toBe('/dir/aaa\\bbb.txt'); - expect(nuclideUri.getPath('nuclide://host/one\\two\\file.txt')).toBe('/one\\two\\file.txt'); - }); -}); diff --git a/pkg/commons-node/spec/observable-spec.js b/pkg/commons-node/spec/observable-spec.js deleted file mode 100644 index aef018718e..0000000000 --- a/pkg/commons-node/spec/observable-spec.js +++ /dev/null @@ -1,443 +0,0 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the license found in the LICENSE file in - * the root directory of this source tree. - * - * @flow - */ - -import { - diffSets, - cacheWhileSubscribed, - nextAnimationFrame, - reconcileSetDiffs, - splitStream, - takeWhileInclusive, - throttle, - toggle, - concatLatest, -} from '../observable'; -import {Disposable} from 'event-kit'; -import {Observable, Subject} from 'rxjs'; - -const setsAreEqual = (a, b) => a.size === b.size && Array.from(a).every(b.has.bind(b)); -const diffsAreEqual = (a, b) => ( - setsAreEqual(a.added, b.added) && setsAreEqual(a.removed, b.removed) -); -const createDisposable = () => { - const disposable = new Disposable(() => {}); - spyOn(disposable, 'dispose'); - return disposable; -}; - -describe('commons-node/observable', () => { - it('splitStream', () => { - waitsForPromise(async () => { - const input = ['foo\nbar', '\n', '\nba', 'z', '\nblar']; - const output = await splitStream(Observable.from(input)).toArray().toPromise(); - expect(output).toEqual(['foo\n', 'bar\n', '\n', 'baz\n', 'blar']); - }); - }); - - describe('takeWhileInclusive', () => { - it('completes the stream when something matches the predicate', () => { - const source = new Subject(); - const result = takeWhileInclusive(source, x => x !== 2); - const next: (n: number) => mixed = jasmine.createSpy(); - const complete: () => mixed = jasmine.createSpy(); - result.subscribe({next, complete}); - source.next(1); - source.next(2); - source.next(3); - expect(complete).toHaveBeenCalled(); - expect(next.calls.map(call => call.args[0])).toEqual([1, 2]); - }); - }); -}); - -describe('cacheWhileSubscribed', () => { - let input: Subject = (null: any); - let output: Observable = (null: any); - - function subscribeArray(arr: Array): rxjs$ISubscription { - return output.subscribe(x => arr.push(x)); - } - beforeEach(() => { - input = new Subject(); - output = cacheWhileSubscribed(input); - }); - - it('should provide cached values to late subscribers', () => { - const arr1 = []; - const arr2 = []; - - input.next(0); - const sub1 = subscribeArray(arr1); - input.next(1); - input.next(2); - const sub2 = subscribeArray(arr2); - - sub1.unsubscribe(); - sub2.unsubscribe(); - expect(arr1).toEqual([1, 2]); - expect(arr2).toEqual([2]); - }); - - it('should not store stale events when everyone is unsubscribed', () => { - const arr1 = []; - const arr2 = []; - - input.next(0); - const sub1 = subscribeArray(arr1); - input.next(1); - sub1.unsubscribe(); - - input.next(2); - - const sub2 = subscribeArray(arr2); - input.next(3); - sub2.unsubscribe(); - - expect(arr1).toEqual([1]); - expect(arr2).toEqual([3]); - }); -}); - -describe('diffSets', () => { - it('emits a diff for the first item', () => { - waitsForPromise(async () => { - const source = new Subject(); - const diffsPromise = diffSets(source).toArray().toPromise(); - source.next(new Set([1, 2, 3])); - source.complete(); - const diffs = await diffsPromise; - expect(diffs.length).toBe(1); - expect(diffsAreEqual(diffs[0], { - added: new Set([1, 2, 3]), - removed: new Set(), - })).toBe(true); - }); - }); - - it('correctly identifies removed items', () => { - waitsForPromise(async () => { - const source = new Subject(); - const diffsPromise = diffSets(source).toArray().toPromise(); - source.next(new Set([1, 2, 3])); - source.next(new Set([1, 2])); - source.complete(); - const diffs = await diffsPromise; - expect(setsAreEqual(diffs[1].removed, new Set([3]))).toBe(true); - }); - }); - - it('correctly identifies removed items when a hash function is used', () => { - waitsForPromise(async () => { - const source = new Subject(); - const diffsPromise = diffSets(source, x => x.key).toArray().toPromise(); - const firstItems = [{key: 1}, {key: 2}, {key: 3}]; - const secondItems = [{key: 1}, {key: 2}]; - source.next(new Set(firstItems)); - source.next(new Set(secondItems)); - source.complete(); - const diffs = await diffsPromise; - expect(setsAreEqual(diffs[1].removed, new Set([firstItems[2]]))).toBe(true); - }); - }); - - it('correctly identifies added items', () => { - waitsForPromise(async () => { - const source = new Subject(); - const diffsPromise = diffSets(source).toArray().toPromise(); - source.next(new Set([1, 2])); - source.next(new Set([1, 2, 3])); - source.complete(); - const diffs = await diffsPromise; - expect(setsAreEqual(diffs[1].added, new Set([3]))).toBe(true); - }); - }); - - it('correctly identifies added items when a hash function is used', () => { - waitsForPromise(async () => { - const source = new Subject(); - const diffsPromise = diffSets(source, x => x.key).toArray().toPromise(); - const firstItems = [{key: 1}, {key: 2}]; - const secondItems = [{key: 1}, {key: 2}, {key: 3}]; - source.next(new Set(firstItems)); - source.next(new Set(secondItems)); - source.complete(); - const diffs = await diffsPromise; - expect(setsAreEqual(diffs[1].added, new Set([secondItems[2]]))).toBe(true); - }); - }); - - it("doesn't emit a diff when nothing changes", () => { - waitsForPromise(async () => { - const source = new Subject(); - const diffsPromise = diffSets(source).toArray().toPromise(); - source.next(new Set([1, 2, 3])); - source.next(new Set([1, 2, 3])); - source.complete(); - const diffs = await diffsPromise; - // Make sure we only get one diff (from the implicit initial empty set). - expect(diffs.length).toBe(1); - }); - }); - - it("doesn't emit a diff when nothing changes and a hash function is used", () => { - waitsForPromise(async () => { - const source = new Subject(); - const diffsPromise = diffSets(source, x => x.key).toArray().toPromise(); - const firstItems = [{key: 1}, {key: 2}, {key: 3}]; - const secondItems = [{key: 1}, {key: 2}, {key: 3}]; - source.next(new Set(firstItems)); - source.next(new Set(secondItems)); - source.complete(); - const diffs = await diffsPromise; - // Make sure we only get one diff (from the implicit initial empty set). - expect(diffs.length).toBe(1); - }); - }); -}); - -describe('reconcileSetDiffs', () => { - it("calls the add action for each item that's added", () => { - const diffs = new Subject(); - const addAction = jasmine.createSpy().andReturn(new Disposable(() => {})); - reconcileSetDiffs(diffs, addAction); - diffs.next({ - added: new Set(['a', 'b']), - removed: new Set(), - }); - expect(addAction.calls.map(call => call.args[0])).toEqual(['a', 'b']); - }); - - it("disposes for each item that's removed", () => { - const diffs = new Subject(); - const disposables = { - a: createDisposable(), - b: createDisposable(), - }; - const addAction = item => disposables[item]; - reconcileSetDiffs(diffs, addAction); - diffs.next({ - added: new Set(['a', 'b']), - removed: new Set(), - }); - diffs.next({ - added: new Set(), - removed: new Set(['a', 'b']), - }); - expect(disposables.a.dispose).toHaveBeenCalled(); - expect(disposables.b.dispose).toHaveBeenCalled(); - }); - - it('disposes for all items when disposed', () => { - const diffs = new Subject(); - const disposables = { - a: createDisposable(), - b: createDisposable(), - }; - const addAction = item => disposables[item]; - const reconciliationDisposable = reconcileSetDiffs(diffs, addAction); - diffs.next({ - added: new Set(['a', 'b']), - removed: new Set(), - }); - reconciliationDisposable.dispose(); - expect(disposables.a.dispose).toHaveBeenCalled(); - expect(disposables.b.dispose).toHaveBeenCalled(); - }); - - it("disposes for each item that's removed when a hash function is used", () => { - const diffs = new Subject(); - const disposables = { - a: createDisposable(), - b: createDisposable(), - }; - const addAction = item => disposables[item.key]; - reconcileSetDiffs(diffs, addAction, x => x.key); - diffs.next({ - added: new Set([{key: 'a'}, {key: 'b'}]), - removed: new Set(), - }); - diffs.next({ - added: new Set(), - removed: new Set([{key: 'a'}, {key: 'b'}]), - }); - expect(disposables.a.dispose).toHaveBeenCalled(); - expect(disposables.b.dispose).toHaveBeenCalled(); - }); -}); - -describe('toggle', () => { - let toggler: Subject = (null: any); - let source: Observable = (null: any); - let output: Observable = (null: any); - let outputArray: Array = (null: any); - - beforeEach(() => { - toggler = new Subject(); - // Deferred so individual 'it' blocks can set the source on the fly. - output = toggle(Observable.defer(() => source), toggler); - }); - - describe('with a standard source', () => { - let realSource: Subject = (null: any); - - beforeEach(() => { - source = realSource = new Subject(); - outputArray = []; - output.subscribe(x => outputArray.push(x)); - }); - - it("should not emit anything before the toggler is set to 'true'", () => { - realSource.next(5); - expect(outputArray).toEqual([]); - }); - - it("should start emitting events when the toggler is set to 'true'", () => { - toggler.next(true); - realSource.next(5); - expect(outputArray).toEqual([5]); - }); - - it("should stop emitting events when the toggler is set to 'false'", () => { - toggler.next(true); - toggler.next(false); - realSource.next(4); - expect(outputArray).toEqual([]); - }); - }); - - // These ones are set apart from the rest because we want a cold observable to explicitly test - // that toggling off unsubscribes and then resubscribes. - describe('subscription behavior', () => { - beforeEach(() => { - source = Observable.of(1, 2, 3); - outputArray = []; - output.subscribe(x => outputArray.push(x)); - }); - - it('should unsubscribe and resusbscribe when toggled off and back on', () => { - expect(outputArray).toEqual([]); - - toggler.next(true); - - expect(outputArray).toEqual([1, 2, 3]); - - toggler.next(false); - toggler.next(true); - - expect(outputArray).toEqual([1, 2, 3, 1, 2, 3]); - }); - - it('should not re-subscribe on duplicate toggler values', () => { - toggler.next(true); - toggler.next(true); - expect(outputArray).toEqual([1, 2, 3]); - }); - }); -}); - -describe('concatLatest', () => { - it('should work with empty input', () => { - waitsForPromise(async () => { - const output = await concatLatest().toArray().toPromise(); - expect(output).toEqual([]); - }); - }); - - it('should work with several observables', () => { - waitsForPromise(async () => { - const output = await concatLatest( - Observable.of([], [1]), - Observable.of([2]), - Observable.of([3], [3, 4]), - ).toArray().toPromise(); - expect(output).toEqual([ - [], - [1], - [1, 2], - [1, 2, 3], - [1, 2, 3, 4], - ]); - }); - }); -}); - -describe('throttle', () => { - it('emits the leading item immeditately by default', () => { - const source = Observable.of(1, 2).merge(Observable.never()); - const spy = jasmine.createSpy(); - throttle(source, Observable.never()).subscribe(spy); - expect(spy).toHaveBeenCalledWith(1); - }); - - it("doesn't emit the leading item twice", () => { - const source = Observable.of(1).merge(Observable.never()); - const notifier = Observable.of(null); // emits immediately on subscription. - const spy = jasmine.createSpy(); - throttle(source, notifier).subscribe(spy); - expect(spy.callCount).toBe(1); - }); - - it('throttles', () => { - const source = new Subject(); - const notifier = new Subject(); - const spy = jasmine.createSpy(); - throttle(source, notifier).subscribe(spy); - source.next(1); - spy.reset(); - source.next(2); - expect(spy).not.toHaveBeenCalled(); - notifier.next(); - expect(spy).toHaveBeenCalledWith(2); - spy.reset(); - source.next(3); - expect(spy).not.toHaveBeenCalled(); - source.next(4); - expect(spy).not.toHaveBeenCalled(); - notifier.next(); - expect(spy).toHaveBeenCalledWith(4); - expect(spy.callCount).toBe(1); - }); - - it('subscribes to the source once per subscription', () => { - const spy = jasmine.createSpy(); - const source = Observable.create(spy); - throttle(source, Observable.of(null)).subscribe(); - expect(spy.callCount).toBe(1); - }); -}); - -describe('nextAnimationFrame', () => { - let oldRequestAnimationFrame; - let oldCancelAnimationFrame; - beforeEach(() => { - oldRequestAnimationFrame = window.requestAnimationFrame; - oldCancelAnimationFrame = window.cancelAnimationFrame; - window.requestAnimationFrame = jasmine.createSpy('requestAnimationFrame'); - window.cancelAnimationFrame = jasmine.createSpy('cancelAnimationFrame'); - }); - - afterEach(() => { - window.requestAnimationFrame = oldRequestAnimationFrame; - window.cancelAnimationFrame = oldCancelAnimationFrame; - }); - - it('schedules next using requestAnimationFrame', () => { - const sub = nextAnimationFrame.subscribe(); - expect(window.requestAnimationFrame).toHaveBeenCalled(); - sub.unsubscribe(); - }); - - it('uses cancelAnimationFrame when unsubscribed', () => { - const sub = nextAnimationFrame.subscribe(); - expect(window.cancelAnimationFrame).not.toHaveBeenCalled(); - sub.unsubscribe(); - expect(window.cancelAnimationFrame).toHaveBeenCalled(); - }); -}); diff --git a/pkg/commons-node/spec/once-spec.js b/pkg/commons-node/spec/once-spec.js deleted file mode 100644 index f1fd7fc0cc..0000000000 --- a/pkg/commons-node/spec/once-spec.js +++ /dev/null @@ -1,20 +0,0 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the license found in the LICENSE file in - * the root directory of this source tree. - * - * @flow - */ - -import once from '../once'; - -describe('once', () => { - it('correctly calls only once', () => { - let num = 1; - const onceFn = once(n => (num += n)); - expect(onceFn(2)).toEqual(3); - expect(onceFn(2)).toEqual(3); - }); -}); diff --git a/pkg/commons-node/spec/process-spec.js b/pkg/commons-node/spec/process-spec.js deleted file mode 100644 index 9f1d4d63ab..0000000000 --- a/pkg/commons-node/spec/process-spec.js +++ /dev/null @@ -1,542 +0,0 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the license found in the LICENSE file in - * the root directory of this source tree. - * - * @flow - */ - -import type {ProcessExitMessage} from '../process-rpc-types'; - -import {sleep} from '../promise'; -import child_process from 'child_process'; -import invariant from 'assert'; -import mockSpawn from 'mock-spawn'; -import path from 'path'; // eslint-disable-line nuclide-internal/prefer-nuclide-uri - -import { - asyncExecute, - checkOutput, - createProcessStream, - getOutputStream, - killProcess, - killUnixProcessTree, - observeProcess, - observeProcessExit, - parsePsOutput, - runCommand, - safeFork, - safeSpawn, - scriptSafeSpawn, - exitEventToMessage, -} from '../process'; - -describe('commons-node/process', () => { - let origPlatform; - - beforeEach(() => { - origPlatform = process.platform; - // Use a fake platform so the platform's PATH is not used in case the test is run on a platform - // that requires special handling (like OS X). - Object.defineProperty(process, 'platform', {value: 'MockMock'}); - }); - - afterEach(() => { - Object.defineProperty(process, 'platform', {value: origPlatform}); - }); - - describe('checkOutput', () => { - if (origPlatform !== 'win32') { - it('returns stdout of the running process', () => { - waitsForPromise(async () => { - const val = await checkOutput('echo', ['-n', 'foo'], {env: process.env}); - expect(val.stdout).toEqual('foo'); - }); - }); - it('throws an error if the exit code !== 0', () => { - waitsForPromise({shouldReject: true}, async () => { - await checkOutput(process.execPath, ['-e', 'process.exit(1)']); - }); - }); - } - }); - - describe('asyncExecute', () => { - if (origPlatform !== 'win32') { - it('asyncExecute returns an error if the process cannot be started', () => { - waitsForPromise(async () => { - const result = await asyncExecute('non_existing_command', /* args */ []); - expect(result.errorCode).toBe('ENOENT'); - }); - }); - it('asyncExecute does not throw an error if the exit code !== 0', () => { - waitsForPromise(async () => { - const {exitCode} = - await asyncExecute(process.execPath, ['-e', 'process.exit(1)']); - expect(exitCode).toBe(1); - }); - }); - it('supports stdin', () => { - waitsForPromise(async () => { - const result = await asyncExecute('cat', [], {stdin: 'test'}); - expect(result.stdout).toBe('test'); - }); - }); - it('supports a timeout', () => { - waitsForPromise(async () => { - jasmine.useRealClock(); - let result = await asyncExecute('sleep', ['5'], {timeout: 100}); - expect(result.errorCode).toBe('EUNKNOWN'); - - result = await asyncExecute('sleep', ['0'], {timeout: 100}); - expect(result.exitCode).toBe(0); - }); - }); - it('enforces maxBuffer', () => { - waitsForPromise(async () => { - const result = await asyncExecute('yes', [], {maxBuffer: 100}); - expect(result.errorMessage).toContain('maxBuffer'); - }); - }); - } - }); - - describe('process.safeFork', () => { - it('should not crash the process on an error', () => { - waitsForPromise(async () => { - spyOn(console, 'error'); // suppress error printing - spyOn(console, 'log'); // suppress log printing - const child = await safeFork('fakeCommand'); - expect(child).not.toBe(null); - expect(child.listeners('error').length).toBeGreaterThan(0); - }); - }); - }); - - describe('process.safeSpawn', () => { - it('should not crash the process on an error', () => { - waitsForPromise(async () => { - spyOn(console, 'error'); // suppress error printing - spyOn(console, 'log'); // suppress log printing - const child = await safeSpawn('fakeCommand'); - expect(child).not.toBe(null); - expect(child.listeners('error').length).toBeGreaterThan(0); - }); - }); - }); - - describe('process.scriptSafeSpawn', () => { - it('should not crash the process on an error.', () => { - waitsForPromise(async () => { - const child = await scriptSafeSpawn('fakeCommand'); - expect(child).not.toBe(null); - expect(child.listeners('error').length).toBeGreaterThan(0); - }); - }); - }); - - describe('process.killProcess', () => { - it('should only kill the process when `killTree` is false', () => { - waitsForPromise(async () => { - const proc = { - kill: jasmine.createSpy(), - }; - spyOn(console, 'error'); // suppress error printing - spyOn(console, 'log'); // suppress log printing - await killProcess((proc: any), false); - expect(proc.kill).toHaveBeenCalled(); - }); - }); - - it('should kill the process tree when `killTree` is true', () => { - waitsForPromise(async () => { - jasmine.useRealClock(); - // Create a tree that's more than level child deep. - const proc = child_process.spawn('bash', ['-c', '( (sleep 1000)& sleep 1000 )& wait']); - spyOn(console, 'error'); // suppress error printing - spyOn(console, 'log'); // suppress log printing - spyOn(process, 'kill').andCallThrough(); - await sleep(250); // Give some time for the processes to spawn. - await killUnixProcessTree(proc); - expect(process.kill.callCount).toBeGreaterThan(2); - }); - }); - - it('should kill the process tree on windows when `killTree` is true', () => { - waitsForPromise(async () => { - const proc = { - pid: 123, - }; - spyOn(console, 'error'); // suppress error printing - spyOn(console, 'log'); // suppress log printing - Object.defineProperty(process, 'platform', {value: 'win32'}); - spyOn(child_process, 'exec'); - await killProcess((proc: any), true); - expect(child_process.exec.calls.length).toBe(1); - expect(child_process.exec.calls[0].args[0]).toBe(`taskkill /pid ${proc.pid} /T /F`); - }); - }); - }); - - describe('process.parsePsOutput', () => { - it('parse `ps` unix output', () => { - const unixPsOut = ' PPID PID COMM\n' - + ' 0 1 /sbin/launchd\n' - + ' 1 42 command with spaces'; - const processList = parsePsOutput(unixPsOut); - expect(processList).toEqual([ - {command: '/sbin/launchd', pid: 1, parentPid: 0}, - {command: 'command with spaces', pid: 42, parentPid: 1}, - ]); - }); - - it('parse `ps` windows output', () => { - const windowsProcessOut = 'ParentProcessId ProcessId Name\r\n' - + ' 0 4 System Process\r\n' - + ' 4 228 smss.exe'; - - const processList = parsePsOutput(windowsProcessOut); - expect(processList).toEqual([ - {command: 'System Process', pid: 4, parentPid: 0}, - {command: 'smss.exe', pid: 228, parentPid: 4}, - ]); - }); - }); - - describe('process.observeProcessExit', () => { - it('exitCode', () => { - waitsForPromise(async () => { - const child = () => safeSpawn(process.execPath, ['-e', 'process.exit(1)']); - const exitMessage = await observeProcessExit(child).toPromise(); - expect(exitMessage).toEqual(makeExitMessage(1)); - }); - }); - - it('exit via signal', () => { - waitsForPromise(async () => { - const child = - () => safeSpawn(process.execPath, ['-e', 'process.kill(process.pid, "SIGTERM")']); - const exitMessage = await observeProcessExit(child).toPromise(); - expect(exitMessage).toEqual({kind: 'exit', exitCode: null, signal: 'SIGTERM'}); - }); - }); - - it('stdout exitCode', () => { - waitsForPromise(async () => { - const child = () => safeSpawn(process.execPath, - ['-e', 'console.log("stdout1\\nstdout2\\n\\n\\n"); process.exit(1);']); - const results = await observeProcess(child).toArray().toPromise(); - expect(results).toEqual([ - {kind: 'stdout', data: 'stdout1\n'}, - {kind: 'stdout', data: 'stdout2\n'}, - {kind: 'stdout', data: '\n'}, - {kind: 'stdout', data: '\n'}, - {kind: 'stdout', data: '\n'}, - {kind: 'exit', exitCode: 1, signal: null}]); - }); - }); - - it('stderr exitCode', () => { - waitsForPromise(async () => { - const child = () => safeSpawn(process.execPath, - ['-e', 'console.error("stderr"); process.exit(42);']); - const results = await observeProcess(child).toArray().toPromise(); - expect(results).toEqual([{kind: 'stderr', data: 'stderr\n'}, - {kind: 'exit', exitCode: 42, signal: null}]); - }); - }); - - it('stdout, stderr and exitCode', () => { - waitsForPromise(async () => { - const child = () => safeSpawn(process.execPath, - ['-e', 'console.error("stderr"); console.log("std out"); process.exit(42);']); - const results = await observeProcess(child).toArray().toPromise(); - expect(results).toEqual([ - {kind: 'stderr', data: 'stderr\n'}, - {kind: 'stdout', data: 'std out\n'}, - {kind: 'exit', exitCode: 42, signal: null}, - ]); - }); - }); - }); - - describe('getOutputStream', () => { - it('captures stdout, stderr and exitCode', () => { - waitsForPromise(async () => { - const child = safeSpawn(process.execPath, - ['-e', 'console.error("stderr"); console.log("std out"); process.exit(42);']); - const results = await getOutputStream(child).toArray().toPromise(); - expect(results).toEqual([ - {kind: 'stderr', data: 'stderr\n'}, - {kind: 'stdout', data: 'std out\n'}, - {kind: 'exit', exitCode: 42, signal: null}, - ]); - }); - }); - - it('captures stdout, stderr and exitCode when passed a promise', () => { - waitsForPromise(async () => { - const child = safeSpawn(process.execPath, - ['-e', 'console.error("stderr"); console.log("std out"); process.exit(42);']); - const results = await getOutputStream(child).toArray().toPromise(); - expect(results).toEqual([ - {kind: 'stderr', data: 'stderr\n'}, - {kind: 'stdout', data: 'std out\n'}, - {kind: 'exit', exitCode: 42, signal: null}, - ]); - }); - }); - }); - - describe('createProcessStream', () => { - it('errors when the process does', () => { - waitsForPromise(async () => { - spyOn(console, 'error'); // suppress error printing - spyOn(console, 'log'); // suppress log printing - const createProcess = () => safeSpawn('fakeCommand'); - const processStream = createProcessStream(createProcess); - let error; - try { - await processStream.toPromise(); - } catch (err) { - error = err; - } - expect(error).toBeDefined(); - invariant(error); - expect(error.code).toBe('ENOENT'); - }); - }); - - it('can be retried', () => { - waitsForPromise(async () => { - spyOn(console, 'error'); // suppress error printing - spyOn(console, 'log'); // suppress log printing - const createProcess = jasmine.createSpy().andCallFake( - () => safeSpawn('fakeCommand'), - ); - try { - await createProcessStream(createProcess) - .retryWhen(errors => ( - errors.scan( - (errorCount, err) => { - // If this is the third time the process has errored (i.e. the have already been - // two errors before), stop retrying. (We try 3 times because because Rx 3 and 4 - // have bugs with retrying shared observables that would give false negatives for - // this test if we only tried twice.) - if (errorCount === 2) { - throw err; - } - return errorCount + 1; - }, - 0, - ) - )) - .toPromise(); - } catch (err) {} - expect(createProcess.callCount).toEqual(3); - }); - }); - - describe('already exited processeses', () => { - it('protects against giving an exited process', () => { - waitsForPromise(async () => { - spyOn(console, 'error'); // suppress error printing - spyOn(console, 'log'); // suppress log printing - const childProcess = safeSpawn('fakeCommand'); - // Wait until after the "error" event is dispatched. (This is what makes the usage - // invalid.) - await new Promise(resolve => process.nextTick(resolve)); - const func = () => createProcessStream(() => childProcess).subscribe(); - expect(func) - .toThrow('Process already exited. (This indicates a race condition in Nuclide.)'); - }); - }); - - it("doesn't complain when given a process that subsequently errors", () => { - waitsForPromise(async () => { - spyOn(console, 'error'); // suppress error printing - spyOn(console, 'log'); // suppress log printing - let error; - try { - await createProcessStream(() => safeSpawn('fakeCommand')).toPromise(); - } catch (err) { - error = err; - } - expect((error: any).code).toBe('ENOENT'); - }); - }); - - it("doesn't complain when given a forked process that errors", () => { - waitsForPromise(async () => { - let error; - const childProcess = child_process.fork( - path.join(__dirname, 'fixtures', 'throw'), - {silent: true}, - ); - try { - await createProcessStream(() => childProcess).toPromise(); - } catch (err) { - error = err; - } - expect(error).toEqual(null); - }); - }); - }); - }); - - describe('scriptSafeSpawn', () => { - let mySpawn = null; - let realSpawn = null; - let realPlatform = null; - - beforeEach(() => { - mySpawn = mockSpawn(); - realSpawn = child_process.spawn; - child_process.spawn = mySpawn; - realPlatform = process.platform; - Object.defineProperty(process, 'platform', {value: 'linux'}); - }); - - afterEach(() => { - invariant(realSpawn != null); - child_process.spawn = realSpawn; - invariant(realPlatform != null); - Object.defineProperty(process, 'platform', {value: realPlatform}); - }); - - describe('scriptSafeSpawn', () => { - const arg = '--arg1 --arg2'; - const bin = '/usr/bin/fakebinary'; - const testCases = [ - {arguments: [arg], expectedCmd: `${bin} '${arg}'`}, - {arguments: arg.split(' '), expectedCmd: `${bin} ${arg}`}, - ]; - for (const testCase of testCases) { - it('should quote arguments', () => { - expect(process.platform).toEqual('linux', 'Platform was not properly mocked.'); - waitsForPromise(async () => { - const child = scriptSafeSpawn(bin, testCase.arguments); - expect(child).not.toBeNull(); - await new Promise((resolve, reject) => { - child.on('close', resolve); - }); - invariant(mySpawn != null); - expect(mySpawn.calls.length).toBe(1); - const args = mySpawn.calls[0].args; - expect(args.length).toBeGreaterThan(0); - expect(args[args.length - 1]).toBe(testCase.expectedCmd); - }); - }); - } - }); - }); - - describe('observeProcess', () => { - it('completes the stream if the process errors', () => { - spyOn(console, 'error'); - spyOn(console, 'log'); // suppress log printing - // If the stream doesn't complete, this will timeout. - waitsForPromise({timeout: 1000}, async () => { - await observeProcess(() => safeSpawn('fakeCommand')).toArray().toPromise(); - }); - }); - }); - - describe('runCommand', () => { - beforeEach(() => { - // Suppress console spew. - spyOn(console, 'error'); - spyOn(console, 'log'); // suppress log printing - }); - - if (origPlatform === 'win32') { return; } - - it('returns stdout of the running process', () => { - waitsForPromise(async () => { - const val = await runCommand('echo', ['-n', 'foo'], {env: process.env}).toPromise(); - expect(val).toEqual('foo'); - }); - }); - - it("throws an error if the process can't be spawned", () => { - waitsForPromise(async () => { - let error; - try { - await runCommand('fakeCommand').toPromise(); - } catch (err) { - error = err; - } - invariant(error != null); - expect(error.name).toBe('ProcessSystemError'); - }); - }); - - it('throws an error if the exit code !== 0', () => { - waitsForPromise(async () => { - let error; - try { - await runCommand(process.execPath, ['-e', 'process.exit(1)']).toPromise(); - } catch (err) { - error = err; - } - invariant(error != null); - expect(error.name).toBe('ProcessExitError'); - expect(error.code).toBe(1); - expect(error.exitMessage).toEqual(makeExitMessage(1)); - }); - }); - - it('accumulates the stdout if the process exits with a non-zero code', () => { - waitsForPromise(async () => { - let error; - try { - await runCommand( - process.execPath, - ['-e', 'process.stdout.write("hola"); process.exit(1)'], - ).toPromise(); - } catch (err) { - error = err; - } - invariant(error != null); - expect(error.stdout).toBe('hola'); - }); - }); - - it('accumulates the stderr if the process exits with a non-zero code', () => { - waitsForPromise(async () => { - let error; - try { - await runCommand( - process.execPath, - ['-e', 'process.stderr.write("oopsy"); process.exit(1)'], - ).toPromise(); - } catch (err) { - error = err; - } - invariant(error != null); - expect(error.stderr).toBe('oopsy'); - }); - }); - }); - - describe('exitEventToMessage', () => { - it('exitCode', () => { - expect(exitEventToMessage(makeExitMessage(1))).toBe('exit code 1'); - }); - - it('signal', () => { - expect(exitEventToMessage({kind: 'exit', exitCode: null, signal: 'SIGTERM'})) - .toBe('signal SIGTERM'); - }); - }); -}); - -function makeExitMessage(exitCode: number): ProcessExitMessage { - return { - kind: 'exit', - exitCode, - signal: null, - }; -} diff --git a/pkg/commons-node/spec/promise-executors-spec.js b/pkg/commons-node/spec/promise-executors-spec.js deleted file mode 100644 index 968cafe869..0000000000 --- a/pkg/commons-node/spec/promise-executors-spec.js +++ /dev/null @@ -1,101 +0,0 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the license found in the LICENSE file in - * the root directory of this source tree. - * - * @flow - */ - -import { - PromisePool, - PromiseQueue, -} from '../promise-executors'; - -describe('PromiseQueue', () => { - // Workarounds to enable setTimeout, as suggested by: - // https://discuss.atom.io/t/solved-settimeout-not-working-firing-in-specs-tests/11427/17 - beforeEach(() => { - jasmine.useRealClock(); - }); - - it('Run three async operations serially and make sure they do not overlap.', () => { - const queue = new PromiseQueue(); - let res1Start = 0; - let res1End = 0; - let res2Start = 0; - let res2End = 0; - let res3Start = 0; - let res3End = 0; - - runs(() => { - queue.submit(async () => { - res1Start = Date.now(); - await new Promise(resolve => { - setTimeout(() => { resolve(res1End = Date.now()); }, 100); - }); - }); - queue.submit(async () => { - res2Start = Date.now(); - await new Promise(resolve => { - setTimeout(() => { resolve(res2End = Date.now()); }, 200); - }); - }); - queue.submit(async () => { - res3Start = Date.now(); - await new Promise(resolve => { - setTimeout(() => { resolve(res3End = Date.now()); }, 300); - }); - }); - }); - - waitsFor(() => res1End && res2End && res3End, 700); - - runs(() => { - // Make sure that none of the executors overlapped. - expect(res1Start).not.toBeGreaterThan(res1End); - expect(res1End).not.toBeGreaterThan(res2Start); - expect(res2Start).not.toBeGreaterThan(res2End); - expect(res2End).not.toBeGreaterThan(res3Start); - expect(res3Start).not.toBeGreaterThan(res3End); - }); - }); -}); - -describe('PromisePool', () => { - beforeEach(() => { - jasmine.useRealClock(); - }); - - it('Run async operations in parallel and do not exceed pool size.', () => { - const poolSize = 3; - const numDelayedExecutors = 30; - const delayMs = 10; - let numRunning = 0; - - const executors = []; - for (let i = 0; i < numDelayedExecutors; i++) { - executors.push(async () => { - numRunning++; - expect(numRunning <= poolSize).toBe(true); - await new Promise(resolve => { - setTimeout(() => { - expect(numRunning <= poolSize).toBe(true); - numRunning--; - resolve(); - }, delayMs); - }); - }); - } - - const queue = new PromisePool(poolSize); - - waitsForPromise(async () => { - const start = Date.now(); - await Promise.all(executors.map(executor => queue.submit(executor))); - const end = Date.now(); - expect(end - start).toBeLessThan(numDelayedExecutors * delayMs / (poolSize - 1)); - }); - }); -}); diff --git a/pkg/commons-node/spec/promise-spec.js b/pkg/commons-node/spec/promise-spec.js deleted file mode 100644 index b00d4b57c4..0000000000 --- a/pkg/commons-node/spec/promise-spec.js +++ /dev/null @@ -1,639 +0,0 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the license found in the LICENSE file in - * the root directory of this source tree. - * - * @flow - */ - -import { - asyncFind, - denodeify, - serializeAsyncCall, - asyncLimit, - asyncFilter, - asyncObjFilter, - asyncSome, - lastly, - retryLimit, - RequestSerializer, - timeoutPromise, -} from '../promise'; -import {expectAsyncFailure} from '../../nuclide-test-helpers'; -import invariant from 'assert'; - -describe('promises::asyncFind()', () => { - it('Empty list of items should resolve to null.', () => { - let isResolved = false; - let observedResult; - let isRejected = false; - let observedError; - - const args = []; - const test = value => { throw new Error('Should not be called.'); }; - - runs(() => { - asyncFind(args, test) - .then(result => { - observedResult = result; - isResolved = true; - }) - .catch(error => { - observedError = error; - isRejected = true; - }); - }); - - waitsFor(() => isResolved || isRejected); - - runs(() => { - expect(isResolved).toBe(true); - expect(observedResult).toBe(null); - expect(isRejected).toBe(false); - expect(observedError).toBe(undefined); - }); - }); - - it('Last item in list resolves.', () => { - let isResolved = false; - let observedResult; - let isRejected = false; - let observedError; - - const args = ['foo', 'bar', 'baz']; - const test = value => { - if (value === 'foo') { - return null; - } else if (value === 'bar') { - return Promise.resolve(null); - } else { - return Promise.resolve('win'); - } - }; - - runs(() => { - asyncFind(args, test) - .then(result => { - observedResult = result; - isResolved = true; - }) - .catch(error => { - observedError = error; - isRejected = true; - }); - }); - - waitsFor(() => isResolved || isRejected); - - runs(() => { - expect(isResolved).toBe(true); - expect(observedResult).toBe('win'); - expect(isRejected).toBe(false); - expect(observedError).toBe(undefined); - }); - }); -}); - -describe('promises::denodeify()', () => { - /** - * Vararg function that assumes that all elements except the last are - * numbers, as the last argument is a callback function. All of the - * other arguments are multiplied together. If the result is not NaN, - * then the callback is called with the product. Otherwise, the callback - * is called with an error. - * - * This function exhibits some of the quirky behavior of Node APIs that - * accept a variable number of arguments in the middle of the parameter list - * rather than at the end. The type signature of this function cannot be - * expressed in Flow. - */ - function asyncProduct(...factors): void { - const callback = factors.pop(); - const product = factors.reduce((previousValue, currentValue) => { - return previousValue * currentValue; - }, 1); - - if (isNaN(product)) { - callback(new Error('product was NaN')); - } else { - callback(null, product); - } - } - - it('resolves Promise when callback succeeds', () => { - const denodeifiedAsyncProduct = denodeify(asyncProduct); - waitsForPromise(async () => { - const trivialProduct = await denodeifiedAsyncProduct(); - expect(trivialProduct).toBe(1); - - const product = await denodeifiedAsyncProduct(1, 2, 3, 4, 5); - expect(product).toBe(120); - }); - }); - - it('rejects Promise when callback fails', () => { - const denodeifiedAsyncProduct = denodeify(asyncProduct); - waitsForPromise(async () => { - await expectAsyncFailure(denodeifiedAsyncProduct('a', 'b'), (error: Error) => { - expect(error.message).toBe('product was NaN'); - }); - }); - }); - - function checksReceiver(expectedReceiver, callback) { - if (this === expectedReceiver) { - callback(null, 'winner'); - } else { - callback(new Error('unexpected receiver')); - } - } - - it('result of denodeify propagates receiver as expected', () => { - const denodeifiedChecksReceiver = denodeify(checksReceiver); - - waitsForPromise(async () => { - const receiver = {denodeifiedChecksReceiver}; - const result = await receiver.denodeifiedChecksReceiver(receiver); - expect(result).toBe('winner'); - }); - - waitsForPromise(async () => { - const receiver = {denodeifiedChecksReceiver}; - await expectAsyncFailure(receiver.denodeifiedChecksReceiver(null), (error: Error) => { - expect(error.message).toBe('unexpected receiver'); - }); - }); - }); -}); - -describe('promises::serializeAsyncCall()', () => { - it('Returns the same result when called after scheduled', () => { - let i = 0; - const asyncFunSpy = jasmine.createSpy('async'); - const oneAsyncCallAtATime = serializeAsyncCall(() => { - i++; - const resultPromise = waitPromise(10, i); - asyncFunSpy(); - return resultPromise; - }); - // Start an async, and resolve to 1 in 10 ms. - const result1Promise = oneAsyncCallAtATime(); - // Schedule the next async, and resolve to 2 in 20 ms. - const result2Promise = oneAsyncCallAtATime(); - // Reuse scheduled promise and resolve to 2 in 20 ms. - const result3Promise = oneAsyncCallAtATime(); - - advanceClock(11); - // Wait for the promise to call the next chain - // That isn't synchrnously guranteed because it happens on `process.nextTick`. - waitsFor(() => asyncFunSpy.callCount === 2); - waitsForPromise(async () => { - advanceClock(11); - const results = await Promise.all([ - result1Promise, result2Promise, result3Promise, - ]); - expect(results).toEqual([1, 2, 2]); - }); - }); - - it('Calls and returns (even if errors) the same number of times if serially called', () => { - waitsForPromise(async () => { - let i = 0; - const oneAsyncCallAtATime = serializeAsyncCall(() => { - i++; - if (i === 4) { - return Promise.reject('ERROR'); - } - return waitPromise(10, i); - }); - const result1Promise = oneAsyncCallAtATime(); - advanceClock(11); - const result1 = await result1Promise; - - const result2Promise = oneAsyncCallAtATime(); - advanceClock(11); - const result2 = await result2Promise; - - const result3Promise = oneAsyncCallAtATime(); - advanceClock(11); - const result3 = await result3Promise; - - const errorPromoise = oneAsyncCallAtATime(); - advanceClock(11); - await expectAsyncFailure(errorPromoise, error => { - expect(error).toBe('ERROR'); - }); - - const result5Promise = oneAsyncCallAtATime(); - advanceClock(11); - const result5 = await result5Promise; - expect([result1, result2, result3, result5]).toEqual([1, 2, 3, 5]); - }); - }); -}); - -describe('promises::asyncLimit()', () => { - beforeEach(() => { - jasmine.useRealClock(); - }); - - it('runs in series if limit is 1', () => { - waitsForPromise(async () => { - const {result, parallelismHistory} = await captureParallelismHistory( - asyncLimit, - [ - [1, 2, 3], - 1, - item => waitPromise(10, item + 1), - ], - ); - expect(parallelismHistory).toEqual([1, 1, 1]); - expect(result).toEqual([2, 3, 4]); - }); - }); - - it('runs with the specified limit, until finishing', () => { - waitsForPromise(async () => { - const {result, parallelismHistory} = await captureParallelismHistory( - asyncLimit, - [ - [1, 2, 3, 4, 5, 6, 7, 8, 9], - 3, - item => waitPromise(10 + item, item - 1), - ], - ); - expect(result).toEqual([0, 1, 2, 3, 4, 5, 6, 7, 8]); - expect(parallelismHistory).toEqual([1, 2, 3, 3, 3, 3, 3, 3, 3]); - }); - }); - - it('works when the limit is bigger than the array length', () => { - waitsForPromise(async () => { - const result = await asyncLimit([1, 2, 3], 10, item => waitPromise(10, item * 2)); - expect(result).toEqual([2, 4, 6]); - }); - }); - - it('a rejected promise rejects the whole call with the error', () => { - waitsForPromise(async () => { - await expectAsyncFailure(asyncLimit([1], 1, async item => { - throw new Error('rejected iterator promise'); - }), (error: Error) => { - expect(error.message).toBe('rejected iterator promise'); - }); - }); - }); - - it('works when the array is empty', () => { - waitsForPromise(async () => { - const result = await asyncLimit([], 1, () => Promise.resolve()); - expect(result).toEqual([]); - }); - }); -}); - -describe('promises::asyncFilter()', () => { - beforeEach(() => { - jasmine.useRealClock(); - }); - - // eslint-disable-next-line max-len - it('filters an array with an async iterator and maximum parallelization when no limit is specified', () => { - waitsForPromise(async () => { - const {result: filtered, parallelismHistory} = await captureParallelismHistory( - asyncFilter, - [ - [1, 2, 3, 4, 5], - item => waitPromise(10 + item, item > 2), - ], - ); - expect(filtered).toEqual([3, 4, 5]); - expect(parallelismHistory).toEqual([1, 2, 3, 4, 5]); - }); - }); - - it('filters an array with a limit on parallelization', () => { - waitsForPromise(async () => { - const {result: filtered, parallelismHistory} = await captureParallelismHistory( - asyncFilter, - [ - [1, 2, 3, 4, 5], - item => waitPromise(10 + item, item > 2), - 3, - ], - ); - expect(filtered).toEqual([3, 4, 5]); - // Increasing promise resolve time will gurantee maximum parallelization. - expect(parallelismHistory).toEqual([1, 2, 3, 3, 3]); - }); - }); -}); - -describe('promises::asyncObjFilter()', () => { - beforeEach(() => { - jasmine.useRealClock(); - }); - - // eslint-disable-next-line max-len - it('filters an object with an async iterator and maximum parallelization when no limit is specified', () => { - waitsForPromise(async () => { - const {result: filtered, parallelismHistory} = await captureParallelismHistory( - asyncObjFilter, - [ - {a: 1, b: 2, c: 3, d: 4, e: 5}, - (value, key) => waitPromise(5 + value, value > 2), - ], - ); - expect(filtered).toEqual({c: 3, d: 4, e: 5}); - expect(parallelismHistory).toEqual([1, 2, 3, 4, 5]); - }); - }); - - it('filters an array with a limit on parallelization', () => { - waitsForPromise(async () => { - const {result: filtered, parallelismHistory} = await captureParallelismHistory( - asyncObjFilter, - [ - {a: 1, b: 2, c: 3, d: 4, e: 5}, - (value, key) => waitPromise(5 + value, value > 2), - 3, - ], - ); - expect(filtered).toEqual({c: 3, d: 4, e: 5}); - // Increasing promise resolve time will gurantee maximum parallelization. - expect(parallelismHistory).toEqual([1, 2, 3, 3, 3]); - }); - }); -}); - -describe('promises::asyncSome()', () => { - beforeEach(() => { - jasmine.useRealClock(); - }); - - // eslint-disable-next-line max-len - it('some an array with an async iterator and maximum parallelization when no limit is specified', () => { - waitsForPromise(async () => { - const {result, parallelismHistory} = await captureParallelismHistory( - asyncSome, - [ - [1, 2, 3, 4, 5], - item => waitPromise(10, item === 6), - ], - ); - expect(result).toEqual(false); - expect(parallelismHistory).toEqual([1, 2, 3, 4, 5]); - }); - }); - - it('some an array with a limit on parallelization', () => { - waitsForPromise(async () => { - const {result, parallelismHistory} = await captureParallelismHistory( - asyncSome, - [ - [1, 2, 3, 4, 5], - item => waitPromise(10 + item, item === 5), - 3, - ], - ); - expect(result).toEqual(true); - expect(parallelismHistory).toEqual([1, 2, 3, 3, 3]); - }); - }); -}); - -describe('promises::lastly', () => { - it('executes after a resolved promise', () => { - waitsForPromise(async () => { - const spy = jasmine.createSpy('spy'); - const result = await lastly(Promise.resolve(1), spy); - expect(result).toBe(1); - expect(spy).toHaveBeenCalled(); - }); - }); - - it('executes after a rejected promise', () => { - waitsForPromise(async () => { - const spy = jasmine.createSpy('spy'); - await expectAsyncFailure(lastly(Promise.reject(2), spy), err => { - expect(err).toBe(2); - }); - expect(spy).toHaveBeenCalled(); - }); - }); - - it('works for async functions', () => { - waitsForPromise(async () => { - const spy = jasmine.createSpy('spy'); - const result = await lastly(Promise.resolve(1), async () => { - spy(); - }); - expect(result).toBe(1); - expect(spy).toHaveBeenCalled(); - }); - }); -}); - -describe('promises::retryLimit()', () => { - beforeEach(() => { - jasmine.useRealClock(); - }); - - it('retries and fails 2 times before resolving to an acceptable result where limit = 5', () => { - waitsForPromise(async () => { - let succeedAfter = 2; - let calls = 0; - let validationCalls = 0; - const retrialsResult = await retryLimit(() => { - return new Promise((resolve, reject) => { - calls++; - if (succeedAfter-- === 0) { - resolve('RESULT'); - } else { - reject('ERROR'); - } - }); - }, result => { - validationCalls++; - return result === 'RESULT'; - }, 5); - expect(calls).toBe(3); - expect(validationCalls).toBe(1); - expect(retrialsResult).toBe('RESULT'); - }); - }); - - it('retries and fails consistently', () => { - waitsForPromise(async () => { - let calls = 0; - let validationCalls = 0; - const failRetriesPromise = retryLimit( - () => { - calls++; - return Promise.reject('ERROR'); - }, - result => { - validationCalls++; - return result != null; - }, - 2, - ); - await expectAsyncFailure(failRetriesPromise, error => { - expect(error).toBe('ERROR'); - }); - expect(calls).toBe(2); - expect(validationCalls).toBe(0); - }); - }); - - it('accepts a null response', () => { - waitsForPromise(async () => { - let succeedAfter = 2; - let calls = 0; - let validationCalls = 0; - const retryResult = await retryLimit( - () => { - calls++; - if (succeedAfter-- === 0) { - return Promise.resolve(null); - } else { - return Promise.resolve('NOT_GOOD'); - } - }, - result => { - validationCalls++; - return result == null; - }, - 5, - ); - expect(retryResult).toBe(null); - expect(calls).toBe(3); - expect(validationCalls).toBe(3); - }); - }); - - it('no valid response is ever got', () => { - waitsForPromise(async () => { - const nonValidRetriesPromise = retryLimit( - () => { - return Promise.resolve('A'); - }, - result => { - return result === 'B'; - }, - 2, - ); - await expectAsyncFailure(nonValidRetriesPromise, error => { - expect(error.message).toBe('No valid response found!'); - }); - }); - }); -}); - -describe('promises::RequestSerializer()', () => { - let requestSerializer: RequestSerializer = (null: any); - - beforeEach(() => { - jasmine.useRealClock(); - requestSerializer = new RequestSerializer(); - }); - - it('gets outdated result for old promises resolving after newer calls', () => { - waitsForPromise(async () => { - const oldPromise = requestSerializer.run(waitPromise(10, 'OLD')); - const newPromise = requestSerializer.run(waitPromise(5, 'NEW')); - const {status: oldStatus} = await oldPromise; - expect(oldStatus).toBe('outdated'); - const newResult = await newPromise; - invariant(newResult.status === 'success'); - expect(newResult.result).toBe('NEW'); - }); - }); - - it('waitForLatestResult: waits for the latest result', () => { - waitsForPromise(async () => { - requestSerializer.run(waitPromise(5, 'OLD')); - requestSerializer.run(waitPromise(10, 'NEW')); - const latestResult = await requestSerializer.waitForLatestResult(); - expect(latestResult).toBe('NEW'); - }); - }); - - it('waitForLatestResult: waits even if the first run did not kick off', () => { - waitsForPromise(async () => { - const latestResultPromise = requestSerializer.waitForLatestResult(); - requestSerializer.run(waitPromise(10, 'RESULT')); - const latestResult = await latestResultPromise; - expect(latestResult).toBe('RESULT'); - }); - }); - - it('waitForLatestResult: does not wait for the first, if the second resolves faster', () => { - waitsForPromise(async () => { - requestSerializer.run(waitPromise(1000000, 'OLD')); // This will never resolve. - requestSerializer.run(waitPromise(10, 'NEW')); - const latestResult = await requestSerializer.waitForLatestResult(); - expect(latestResult).toBe('NEW'); - }); - }); -}); - -describe('timeoutPromise', () => { - it('should resolve normally if within the timeout', () => { - waitsForPromise(async () => { - const inputPromise = new Promise(resolve => resolve('foo')); - const outputPromise = timeoutPromise(inputPromise, 1000); - expect(await outputPromise).toBe('foo'); - }); - }); - - it('should reject if the given promise rejects', () => { - waitsForPromise(async () => { - const inputPromise = new Promise((resolve, reject) => reject('foo')); - const outputPromise = timeoutPromise(inputPromise, 1000) - .catch(value => `rejected with ${value}`); - expect(await outputPromise).toBe('rejected with foo'); - }); - }); - - it('should reject if the given promise takes too long', () => { - waitsForPromise(async () => { - const inputPromise = new Promise(resolve => setTimeout(resolve, 2000)); - const outputPromise = timeoutPromise(inputPromise, 1000) - .catch(value => value); - advanceClock(1500); - expect(await outputPromise).toEqual(new Error('Promise timed out after 1000 ms')); - }); - }); -}); - - -async function captureParallelismHistory( - asyncFunction: (...args: Array) => Promise, - args: Array, -): Promise<{result: mixed, parallelismHistory: Array}> { - const parallelismHistory = []; - let parralelism = 0; - const result = await asyncFunction(...args.map(arg => { - if (typeof arg !== 'function') { - return arg; - } - const func = arg; - return async item => { - ++parralelism; - parallelismHistory.push(parralelism); - const value = await func(item); - --parralelism; - return value; - }; - })); - return {result, parallelismHistory}; -} - -function waitPromise(timeoutMs: number, value: any): Promise { - return new Promise((resolve, reject) => { - setTimeout(() => resolve(value), timeoutMs); - }); -} diff --git a/pkg/commons-node/spec/scheduleIdleCallback-spec.js b/pkg/commons-node/spec/scheduleIdleCallback-spec.js deleted file mode 100644 index cdb4e2d0d7..0000000000 --- a/pkg/commons-node/spec/scheduleIdleCallback-spec.js +++ /dev/null @@ -1,143 +0,0 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the license found in the LICENSE file in - * the root directory of this source tree. - * - * @flow - */ - -describe('scheduleIdleCallback using node API', () => { - let oldSetImmediate; - let oldClearImmediate; - let setImmediateCalls; - let clearImmediateCalls; - let scheduleIdleCallback; - let oldRequestIdleCallback; - - beforeEach(() => { - oldRequestIdleCallback = global.requestIdleCallback; - delete global.requestIdleCallback; - - oldSetImmediate = global.setImmediate; - setImmediateCalls = []; - global.setImmediate = (...args) => { - setImmediateCalls.push(args); - return 1; - }; - - oldClearImmediate = global.clearImmediate; - clearImmediateCalls = []; - global.clearImmediate = (...args) => { - clearImmediateCalls.push(args); - }; - - delete require.cache[require.resolve('../scheduleIdleCallback')]; - scheduleIdleCallback = require('../scheduleIdleCallback'); - }); - - afterEach(() => { - global.clearImmediate = oldClearImmediate; - global.setImmediate = oldSetImmediate; - global.requestIdleCallback = oldRequestIdleCallback; - delete require.cache[require.resolve('../scheduleIdleCallback')]; - }); - - it('works', () => { - const fnCalls = []; - const fn = () => { - fnCalls.push([]); - }; - const disposable = scheduleIdleCallback(fn); - expect(setImmediateCalls.length).toBe(1); - expect(setImmediateCalls[0][0]).toBe(fn); - expect(clearImmediateCalls.length).toBe(0); - - disposable.dispose(); - expect(clearImmediateCalls.length).toBe(1); - }); -}); - -describe('scheduleIdleCallback using browser API', () => { - let oldRequestIdleCallback; - let oldCancelIdleCallback; - let requestIdleCallbackCalls; - let cancelIdleCallbackCalls; - let scheduleIdleCallback; - - beforeEach(() => { - oldRequestIdleCallback = global.requestIdleCallback; - requestIdleCallbackCalls = []; - let count = 1; - global.requestIdleCallback = (...args) => { - requestIdleCallbackCalls.push(args); - return count++; - }; - - oldCancelIdleCallback = global.cancelIdleCallback; - cancelIdleCallbackCalls = []; - global.cancelIdleCallback = (...args) => { - cancelIdleCallbackCalls.push(args); - }; - - delete require.cache[require.resolve('../scheduleIdleCallback')]; - scheduleIdleCallback = require('../scheduleIdleCallback'); - }); - - afterEach(() => { - global.cancelIdleCallback = oldCancelIdleCallback; - global.requestIdleCallback = oldRequestIdleCallback; - delete require.cache[require.resolve('../scheduleIdleCallback')]; - }); - - it('works', () => { - const fnCalls = []; - const fn = () => { - fnCalls.push([]); - }; - const disposable = scheduleIdleCallback(fn); - expect(requestIdleCallbackCalls.length).toBe(1); - requestIdleCallbackCalls[0][0]({timeRemaining: () => 48}); - expect(fnCalls.length).toBe(0); - expect(requestIdleCallbackCalls.length).toBe(2); - requestIdleCallbackCalls[1][0]({timeRemaining: () => 49}); - expect(fnCalls.length).toBe(1); - expect(cancelIdleCallbackCalls.length).toBe(0); - - disposable.dispose(); - expect(cancelIdleCallbackCalls.length).toBe(0); - }); - - it('cancels', () => { - const disposable = scheduleIdleCallback(() => {}); - requestIdleCallbackCalls[0][0]({timeRemaining: () => 48}); - disposable.dispose(); - expect(cancelIdleCallbackCalls.length).toBe(1); - disposable.dispose(); - expect(cancelIdleCallbackCalls.length).toBe(1); - }); - - it('expires after a timeout', () => { - let curDate = 0; - jasmine.unspy(Date, 'now'); - spyOn(Date, 'now').andCallFake(() => curDate); - const fn = jasmine.createSpy('callback'); - const disposable = scheduleIdleCallback(fn, { - afterRemainingTime: 100, - timeout: 100, - }); - - requestIdleCallbackCalls[0][0]({timeRemaining: () => 48}); - expect(fn).not.toHaveBeenCalled(); - curDate = 50; - requestIdleCallbackCalls[0][0]({timeRemaining: () => 48}); - expect(fn).not.toHaveBeenCalled(); - curDate = 100; - requestIdleCallbackCalls[0][0]({timeRemaining: () => 48}); - expect(fn).toHaveBeenCalled(); - - disposable.dispose(); - expect(cancelIdleCallbackCalls.length).toBe(0); - }); -}); diff --git a/pkg/commons-node/spec/scripts/scribe_cat_mock b/pkg/commons-node/spec/scripts/scribe_cat_mock deleted file mode 100755 index 8ac2562c41..0000000000 --- a/pkg/commons-node/spec/scripts/scribe_cat_mock +++ /dev/null @@ -1,27 +0,0 @@ -#!/usr/bin/env python - -# Copyright (c) 2015-present, Facebook, Inc. -# All rights reserved. -# -# This source code is licensed under the license found in the LICENSE file in -# the root directory of this source tree. - -'''A script simulate scribe_cat and save the stdin into os.environ[SCRIBE_MOCK_PATH]/$category_name file. - To simulate the crash, if the input line is "abort" (quote included), it crash itself with exit code 1.''' - -import optparse -import os -import sys - -parser = optparse.OptionParser(usage='usage: %prog [category_name]', - description='Save stdin into $SCRIBE_MOCK_PATH/$categor_name') -options, args = parser.parse_args(sys.argv[1:]) -category_name = args[0]; - -with open(os.path.join(os.environ['SCRIBE_MOCK_PATH'], category_name), 'a') as f: - while True: - line = sys.stdin.readline() - if line == '': - sys.exit(1) - f.write(line) - f.flush(); diff --git a/pkg/commons-node/spec/singleton-spec.js b/pkg/commons-node/spec/singleton-spec.js deleted file mode 100644 index 1de49926a8..0000000000 --- a/pkg/commons-node/spec/singleton-spec.js +++ /dev/null @@ -1,53 +0,0 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the license found in the LICENSE file in - * the root directory of this source tree. - * - * @flow - */ - -import singleton from '../singleton'; - -describe('singleton', () => { - let count = 0; - const field = 'singleton-test-field'; - - function get() { - return singleton.get(field, () => { return count++; }); - } - - function clear() { - singleton.clear(field); - } - - function reset() { - return singleton.reset(field, () => { return count++; }); - } - - it('get', () => { - const id1 = get(); - const id2 = get(); - expect(id1).toEqual(id2); - }); - - it('clear', () => { - const id1 = get(); - - clear(); - - const id2 = get(); - expect(id2 !== id1).toBe(true); - }); - - it('reset', () => { - const id1 = get(); - - const id2 = reset(); - expect(id2).not.toEqual(id1); - - const id3 = get(); - expect(id3).toEqual(id2); - }); -}); diff --git a/pkg/commons-node/spec/stream-spec.js b/pkg/commons-node/spec/stream-spec.js deleted file mode 100644 index 1a0d4107ee..0000000000 --- a/pkg/commons-node/spec/stream-spec.js +++ /dev/null @@ -1,49 +0,0 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the license found in the LICENSE file in - * the root directory of this source tree. - * - * @flow - */ - -import {observeStream} from '../stream'; -import Stream from 'stream'; - -describe('commons-node/stream', () => { - it('observeStream', () => { - waitsForPromise(async () => { - const input = ['foo\nbar', '\n', '\nba', 'z', '\nblar']; - const stream = new Stream.PassThrough(); - const promise = observeStream(stream).toArray().toPromise(); - input.forEach(value => { stream.write(value, 'utf8'); }); - stream.end(); - const output = await promise; - expect(output.join('')).toEqual(input.join('')); - }); - }); - - it('observeStream - error', () => { - waitsForPromise(async () => { - const stream = new Stream.PassThrough(); - const input = ['foo\nbar', '\n', '\nba', 'z', '\nblar']; - const output = []; - const promise = new Promise((resolve, reject) => { - observeStream(stream).subscribe( - v => output.push(v), - e => resolve(e), - () => {}, - ); - }); - const error = new Error('Had an error'); - - input.forEach(value => { stream.write(value, 'utf8'); }); - stream.emit('error', error); - - const result = await promise; - expect(output).toEqual(input); - expect(result).toBe(error); - }); - }); -}); diff --git a/pkg/commons-node/spec/string-spec.js b/pkg/commons-node/spec/string-spec.js deleted file mode 100644 index f7ba702f18..0000000000 --- a/pkg/commons-node/spec/string-spec.js +++ /dev/null @@ -1,174 +0,0 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the license found in the LICENSE file in - * the root directory of this source tree. - * - * @flow - */ - -import { - maybeToString, - relativeDate, - countOccurrences, - shellParse, - shorten, - removeCommonPrefix, - removeCommonSuffix, -} from '../string'; - -describe('relativeDate', () => { - it('works', () => { - const SECOND = 1000; - const MINUTE = 60 * SECOND; - const HOUR = 60 * MINUTE; - const DAY = 24 * HOUR; - const WEEK = 7 * DAY; - const YEAR = DAY * 365; - const MONTH = YEAR / 12; - - const reference = 157765000000; // 01.01.1975 00:00 - const now = new Date().getTime(); - - // test long format - expect(relativeDate(0)).toEqual(Math.round(now / YEAR) + ' years ago'); - expect(relativeDate(reference * SECOND, reference)).toEqual('just now'); - expect(relativeDate(reference - 41 * SECOND, reference)).toEqual('just now'); - expect(relativeDate(reference - 42 * SECOND, reference)).toEqual('a minute ago'); - expect(relativeDate(reference - MINUTE, reference)).toEqual('a minute ago'); - expect(relativeDate(reference - MINUTE * 1.5, reference)).toEqual('2 minutes ago'); - expect(relativeDate(reference - MINUTE * 59, reference)).toEqual('59 minutes ago'); - expect(relativeDate(reference - HOUR, reference)).toEqual('an hour ago'); - expect(relativeDate(reference - HOUR * 1.5, reference)).toEqual('2 hours ago'); - expect(relativeDate(reference - HOUR * 16, reference)).toEqual('16 hours ago'); - expect(relativeDate(reference - HOUR * 23, reference)).toEqual('23 hours ago'); - expect(relativeDate(reference - DAY * 1.8, reference)).toEqual('yesterday'); - expect(relativeDate(reference - DAY * 3, reference)).toEqual('3 days ago'); - expect(relativeDate(reference - DAY * 6, reference)).toEqual('6 days ago'); - expect(relativeDate(reference - WEEK, reference)).toEqual('a week ago'); - expect(relativeDate(reference - WEEK * 2, reference)).toEqual('2 weeks ago'); - expect(relativeDate(reference - WEEK * 4, reference)).toEqual('4 weeks ago'); - expect(relativeDate(reference - MONTH * 1.2, reference)).toEqual('a month ago'); - expect(relativeDate(reference - YEAR + HOUR, reference)).toEqual('12 months ago'); - expect(relativeDate(reference - YEAR, reference)).toEqual('a year ago'); - expect(relativeDate(reference - YEAR * 2, reference)).toEqual('2 years ago'); - expect(relativeDate(0, reference)).toEqual('5 years ago'); - - // test short format - expect(relativeDate(0, undefined, /* short */ true)).toEqual(Math.round(now / YEAR) + 'y'); - expect(relativeDate(reference * SECOND, reference, /* short */ true)).toEqual('now'); - expect(relativeDate(reference - 41 * SECOND, reference, /* short */ true)).toEqual('now'); - expect(relativeDate(reference - 42 * SECOND, reference, /* short */ true)).toEqual('1m'); - expect(relativeDate(reference - MINUTE, reference, /* short */ true)).toEqual('1m'); - expect(relativeDate(reference - MINUTE * 1.5, reference, /* short */ true)).toEqual('2m'); - expect(relativeDate(reference - MINUTE * 59, reference, /* short */ true)).toEqual('59m'); - expect(relativeDate(reference - HOUR, reference, /* short */ true)).toEqual('1h'); - expect(relativeDate(reference - HOUR * 1.5, reference, /* short */ true)).toEqual('2h'); - expect(relativeDate(reference - HOUR * 16, reference, /* short */ true)).toEqual('16h'); - expect(relativeDate(reference - HOUR * 23, reference, /* short */ true)).toEqual('23h'); - expect(relativeDate(reference - DAY * 1.8, reference, /* short */ true)).toEqual('1d'); - expect(relativeDate(reference - DAY * 3, reference, /* short */ true)).toEqual('3d'); - expect(relativeDate(reference - DAY * 6, reference, /* short */ true)).toEqual('6d'); - expect(relativeDate(reference - WEEK, reference, /* short */ true)).toEqual('1w'); - expect(relativeDate(reference - WEEK * 2, reference, /* short */ true)).toEqual('2w'); - expect(relativeDate(reference - WEEK * 4, reference, /* short */ true)).toEqual('4w'); - expect(relativeDate(reference - MONTH * 1.2, reference, /* short */ true)).toEqual('1mo'); - expect(relativeDate(reference - YEAR + HOUR, reference, /* short */ true)).toEqual('12mo'); - expect(relativeDate(reference - YEAR, reference, /* short */ true)).toEqual('1y'); - expect(relativeDate(reference - YEAR * 2, reference, /* short */ true)).toEqual('2y'); - expect(relativeDate(0, reference, /* short */ true)).toEqual('5y'); - }); -}); - -describe('maybeToString', () => { - it("returns 'undefined'", () => { - expect(maybeToString(undefined)).toEqual('undefined'); - }); - - it("returns 'null'", () => { - expect(maybeToString(null)).toEqual('null'); - }); - - it('returns an ordinary string', () => { - expect(maybeToString('foo')).toEqual('foo'); - }); -}); - -describe('countOccurrences', () => { - it('counts the number of characters', () => { - expect(countOccurrences('abcaaa', 'a')).toBe(4); - }); - - it('throws for non-length-1 searches', () => { - expect(() => { - countOccurrences('abc', 'abc'); - }).toThrow(); - }); -}); - -describe('shellParse', () => { - it('parses a list of arguments', () => { - expect(shellParse('1 2 3 "a b c"')).toEqual(['1', '2', '3', 'a b c']); - }); - - it('throws if operators are given', () => { - expect(() => { - shellParse('a | b'); - }).toThrow(Error('Unexpected operator "|" provided to shellParse')); - expect(() => { - shellParse('a > b'); - }).toThrow(Error('Unexpected operator ">" provided to shellParse')); - }); -}); - -describe('removeCommonPrefix', () => { - it('does nothing if there is no common prefix', () => { - expect(removeCommonPrefix('foo', 'bar')).toEqual(['foo', 'bar']); - }); - - it('removes a common prefix', () => { - expect(removeCommonPrefix('foo', 'fbar')).toEqual(['oo', 'bar']); - expect(removeCommonPrefix('asdffoo', 'asdfbar')).toEqual(['foo', 'bar']); - }); - - it('works with the empty string', () => { - expect(removeCommonPrefix('', 'bar')).toEqual(['', 'bar']); - expect(removeCommonPrefix('foo', '')).toEqual(['foo', '']); - expect(removeCommonPrefix('', '')).toEqual(['', '']); - }); - - it('returns empty strings for identical strings', () => { - expect(removeCommonPrefix('foo', 'foo')).toEqual(['', '']); - }); -}); - -describe('removeCommonSuffix', () => { - it('does nothing if there is no common suffix', () => { - expect(removeCommonSuffix('foo', 'bar')).toEqual(['foo', 'bar']); - }); - - it('removes a common suffix', () => { - expect(removeCommonSuffix('foo', 'baro')).toEqual(['fo', 'bar']); - expect(removeCommonSuffix('fooasdf', 'baroasdf')).toEqual(['fo', 'bar']); - }); - - it('works with the empty string', () => { - expect(removeCommonSuffix('', 'bar')).toEqual(['', 'bar']); - expect(removeCommonSuffix('foo', '')).toEqual(['foo', '']); - expect(removeCommonSuffix('', '')).toEqual(['', '']); - }); - - it('returns empty strings for identical strings', () => { - expect(removeCommonSuffix('foo', 'foo')).toEqual(['', '']); - }); -}); - -describe('shorten', () => { - it('works', () => { - expect(shorten('', 1)).toEqual(''); - expect(shorten('test', 3)).toEqual('tes'); - expect(shorten('test', 100)).toEqual('test'); - expect(shorten('test', 1, '...')).toEqual('t...'); - }); -}); diff --git a/pkg/commons-node/spec/tasks-spec.js b/pkg/commons-node/spec/tasks-spec.js deleted file mode 100644 index 922a4191df..0000000000 --- a/pkg/commons-node/spec/tasks-spec.js +++ /dev/null @@ -1,170 +0,0 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the license found in the LICENSE file in - * the root directory of this source tree. - * - * @flow - */ - -import {taskFromObservable, observableFromTask} from '../tasks'; -import invariant from 'assert'; -import {Emitter} from 'event-kit'; -import {Observable, Subject, Subscription} from 'rxjs'; - -describe('commons-node/tasks', () => { - describe('observableFromTask', () => { - it('calls start when subscribed', () => { - const task = createMockTask(); - const observable = observableFromTask(task); - expect(task.start).not.toHaveBeenCalled(); - observable.subscribe(); - expect(task.start).toHaveBeenCalled(); - }); - - it('calls cancel when unsubscribed early', () => { - const task = createMockTask(); - const observable = observableFromTask(task); - const sub = observable.subscribe(); - expect(task.cancel).not.toHaveBeenCalled(); - sub.unsubscribe(); - expect(task.cancel).toHaveBeenCalled(); - }); - - it('completes when the task does', () => { - const task = createMockTask(); - const observable = observableFromTask(task); - const completed = jasmine.createSpy(); - observable.subscribe({complete: completed}); - expect(completed).not.toHaveBeenCalled(); - task._complete(); - expect(completed).toHaveBeenCalled(); - }); - - it('errors when the task does', () => { - const task = createMockTask(); - const observable = observableFromTask(task); - const errored = jasmine.createSpy(); - observable.subscribe({error: errored}); - expect(errored).not.toHaveBeenCalled(); - task._error(new Error()); - expect(errored).toHaveBeenCalled(); - }); - - it("doesn't call cancel when unsubscribed after completion", () => { - const task = createMockTask(); - const observable = observableFromTask(task); - const sub = observable.subscribe(); - task._complete(); - sub.unsubscribe(); - expect(task.cancel).not.toHaveBeenCalled(); - }); - - it("doesn't call cancel when unsubscribed after an error", () => { - const task = createMockTask(); - const observable = observableFromTask(task); - const sub = observable.catch(() => Observable.empty()).subscribe(); - task._error(new Error()); - sub.unsubscribe(); - expect(task.cancel).not.toHaveBeenCalled(); - }); - - it('includes emitted progress events', () => { - const task = createMockTask(); - const observable = observableFromTask(task); - const handler = jasmine.createSpy(); - observable.subscribe(handler); - task._progress(0.5); - expect(handler).toHaveBeenCalledWith({type: 'progress', progress: 0.5}); - }); - }); - - describe('taskFromObservable', () => { - it('subscribes when started', () => { - const observable = new Subject(); - spyOn(observable, 'subscribe').andCallThrough(); - const task = taskFromObservable(observable); - expect(observable.subscribe).not.toHaveBeenCalled(); - task.start(); - expect(observable.subscribe).toHaveBeenCalled(); - }); - - it('unsubscribes when canceled', () => { - const sub = new Subscription(); - spyOn(sub, 'unsubscribe'); - const observable = new Subject(); - spyOn(observable, 'subscribe').andReturn(sub); - const task = taskFromObservable(observable); - task.start(); - expect(sub.unsubscribe).not.toHaveBeenCalled(); - task.cancel(); - expect(sub.unsubscribe).toHaveBeenCalled(); - }); - - it('calls onDidComplete callbacks when it completes', () => { - const sub = new Subscription(); - spyOn(sub, 'unsubscribe'); - const observable = new Subject(); - const task = taskFromObservable(observable); - const completed = jasmine.createSpy(); - task.onDidComplete(completed); - task.start(); - expect(completed).not.toHaveBeenCalled(); - observable.complete(); - expect(completed).toHaveBeenCalled(); - }); - - it('calls onDidError callbacks when it errors', () => { - const observable = new Subject(); - const task = taskFromObservable(observable); - const errored = jasmine.createSpy(); - task.onDidError(errored); - task.start(); - expect(errored).not.toHaveBeenCalled(); - observable.error(); - expect(errored).toHaveBeenCalled(); - }); - - it('calls onProgress callbacks for progress events', () => { - const observable = new Subject(); - const task = taskFromObservable(observable); - const handler = jasmine.createSpy(); - invariant(task.onProgress != null); - task.onProgress(handler); - task.start(); - expect(handler).not.toHaveBeenCalled(); - observable.next({type: 'progress', progress: 0.5}); - expect(handler).toHaveBeenCalledWith(0.5); - }); - }); -}); - -function createMockTask() { - const emitter = new Emitter(); - const task = { - start: () => {}, - cancel: () => {}, - onDidComplete: (callback: () => mixed): IDisposable => { - return emitter.on('complete', callback); - }, - onDidError: (callback: (err: Error) => mixed): IDisposable => { - return emitter.on('error', callback); - }, - onProgress: (callback: (progress: ?number) => mixed): IDisposable => { - return emitter.on('progress', callback); - }, - _complete: (): void => { - emitter.emit('complete'); - }, - _error: (err: Error): void => { - emitter.emit('error', err); - }, - _progress: (progress: ?number): void => { - emitter.emit('progress', progress); - }, - }; - spyOn(task, 'start'); - spyOn(task, 'cancel'); - return task; -} diff --git a/pkg/commons-node/spec/which-spec.js b/pkg/commons-node/spec/which-spec.js deleted file mode 100644 index 8dcac564a6..0000000000 --- a/pkg/commons-node/spec/which-spec.js +++ /dev/null @@ -1,85 +0,0 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the license found in the LICENSE file in - * the root directory of this source tree. - * - * @flow - */ - -import which from '../which'; - -describe('which', () => { - let checkOutput: JasmineSpy; - let checkOutputReturn: {stdout: string} = (null: any); - - beforeEach(() => { - checkOutputReturn = {stdout: ''}; - checkOutput = spyOn(require('../process'), 'checkOutput').andCallFake(() => - checkOutputReturn, - ); - }); - - afterEach(() => { - jasmine.unspy(require('../process'), 'checkOutput'); - }); - - describe('on windows', () => { - const real_platform: string = process.platform; - const eol = '\r\n'; - const os = require('os'); - const real_eol = os.EOL; - beforeEach(() => { - Object.defineProperty(process, 'platform', {value: 'win32'}); - os.EOL = eol; - }); - afterEach(() => { - Object.defineProperty(process, 'platform', {value: real_platform}); - os.EOL = real_eol; - }); - - it('calls where on Windows', () => { - const param: string = ''; - which(param); - expect(checkOutput).toHaveBeenCalledWith('where', [param]); - }); - - it('returns the first match', () => { - waitsForPromise(async () => { - checkOutputReturn.stdout = 'hello' + os.EOL + 'hello.exe' + os.EOL; - const ret = await which('bla'); - expect(ret).toEqual('hello'); - }); - }); - }); - - describe('on linux', () => { - const real_platform: string = process.platform; - const eol = '\n'; - const os = require('os'); - const real_eol = os.EOL; - beforeEach(() => { - Object.defineProperty(process, 'platform', {value: 'linux'}); - os.EOL = eol; - }); - afterEach(() => { - Object.defineProperty(process, 'platform', {value: real_platform}); - os.EOL = real_eol; - }); - - it('calls which', () => { - const param: string = ''; - which(param); - expect(checkOutput).toHaveBeenCalledWith('which', [param]); - }); - - it('returns the first match', () => { - waitsForPromise(async () => { - checkOutputReturn.stdout = 'hello' + os.EOL + '/bin/hello' + os.EOL; - const ret = await which('bla'); - expect(ret).toEqual('hello'); - }); - }); - }); -}); diff --git a/pkg/commons-node/spec/wootr-spec.js b/pkg/commons-node/spec/wootr-spec.js deleted file mode 100644 index 6d86c8af1c..0000000000 --- a/pkg/commons-node/spec/wootr-spec.js +++ /dev/null @@ -1,684 +0,0 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the license found in the LICENSE file in - * the root directory of this source tree. - * - * @flow - */ - -import invariant from 'assert'; - -import {WString} from '../wootr'; - -describe('wootr', () => { - describe('insert', () => { - it('should allow a whole string to be passed in', () => { - const wstring = new WString(1, 50000000); - - expect(wstring._string[1]).toEqual({ - length: 50000000, - startId: { - site: 1, - h: 1, - }, - startDegree: 1, - visible: true, - }); - - expect(wstring._string.length).toEqual(3); - }); - - it('should combine adjacent runs', () => { - const wstring = new WString(1); - wstring.insert(1, {startId: {site: 1, h: 1}, visible: true, startDegree: 1, length: 1}); - wstring.insert(2, {startId: {site: 1, h: 2}, visible: true, startDegree: 2, length: 1}); - wstring.insert(3, {startId: {site: 1, h: 3}, visible: true, startDegree: 3, length: 1}); - wstring.insert(4, {startId: {site: 1, h: 4}, visible: true, startDegree: 4, length: 1}); - - expect(wstring._string[1]).toEqual({ - length: 4, - startId: { - site: 1, - h: 1, - }, - startDegree: 1, - visible: true, - }); - expect(wstring._string.length).toEqual(3); - }); - - it('should append run when inserted after incompatible run', () => { - const wstring = new WString(1); - - wstring.insert(1, {startId: {site: 1, h: 1}, visible: true, startDegree: 1, length: 1}); - wstring.insert(2, {startId: {site: 2, h: 1}, visible: true, startDegree: 2, length: 1}); - - expect(wstring._string[1]).toEqual({ - length: 1, - startId: { - site: 1, - h: 1, - }, - startDegree: 1, - visible: true, - }); - - expect(wstring._string[2]).toEqual({ - length: 1, - startId: { - site: 2, - h: 1, - }, - startDegree: 2, - visible: true, - }); - - expect(wstring._string.length).toEqual(4); - }); - - it('should split runs when inserted inside a run', () => { - const wstring = new WString(1); - - wstring.insert(1, {startId: {site: 1, h: 1}, visible: true, startDegree: 1, length: 1}); - wstring.insert(2, {startId: {site: 1, h: 2}, visible: true, startDegree: 2, length: 1}); - wstring.insert(2, {startId: {site: 1, h: 3}, visible: true, startDegree: 3, length: 1}); - wstring.insert(3, {startId: {site: 1, h: 4}, visible: true, startDegree: 4, length: 1}); - - expect(wstring._string[1]).toEqual({ - length: 1, - startId: { - site: 1, - h: 1, - }, - startDegree: 1, - visible: true, - }); - - expect(wstring._string[2]).toEqual({ - length: 2, - startId: { - site: 1, - h: 3, - }, - startDegree: 3, - visible: true, - }); - - expect(wstring._string[3]).toEqual({ - length: 1, - startId: { - site: 1, - h: 2, - }, - startDegree: 2, - visible: true, - }); - - expect(wstring._string.length).toEqual(5); - }); - - it('should be the same wstrings when you ' + - 'insert 4 length 1 chars and 1 length 4 char', () => { - const wstring = new WString(1); - const wstring2 = new WString(2); - wstring.insert(1, {startId: {site: 1, h: 1}, visible: true, startDegree: 1, length: 1}); - wstring.insert(2, {startId: {site: 1, h: 2}, visible: true, startDegree: 2, length: 1}); - wstring.insert(3, {startId: {site: 1, h: 3}, visible: true, startDegree: 3, length: 1}); - wstring.insert(4, {startId: {site: 1, h: 4}, visible: true, startDegree: 4, length: 1}); - - wstring2.insert(1, {startId: {site: 1, h: 1}, visible: true, startDegree: 1, length: 4}); - - expect(wstring2._string).toEqual(wstring._string); - }); - }); - - describe('integrateDelete', () => { - it('not left edge; not right edge; no merge left; no merge right', () => { - const wstring = new WString(1, 3); // [+++] - wstring.integrateDelete(2); // [+][-][+] - - expect(wstring._string.length).toEqual(5); - expect(wstring._string[1]).toEqual({ - length: 1, - startDegree: 1, - startId: { - h: 1, - site: 1, - }, - visible: true, - }); - expect(wstring._string[2]).toEqual({ - length: 1, - startDegree: 2, - startId: { - h: 2, - site: 1, - }, - visible: false, - }); - expect(wstring._string[3]).toEqual({ - length: 1, - startDegree: 3, - startId: { - h: 3, - site: 1, - }, - visible: true, - }); - }); - - it('left edge; right edge; merge left; merge right', () => { - const wstring = new WString(1, 3); // [+++] - wstring.integrateDelete(3); // [++][-] - wstring.integrateDelete(1); // [-][+][-] - wstring.integrateDelete(1); // [---] - - expect(wstring._string.length).toEqual(3); - expect(wstring._string[1]).toEqual({ - length: 3, - startDegree: 1, - startId: { - h: 1, - site: 1, - }, - visible: false, - }); - }); - - it('left edge; not right edge; merge left; no merge right', () => { - const wstring = new WString(1, 3); // [+++] - wstring.integrateDelete(1); // [-][++] - wstring.integrateDelete(1); // [--][+] - - expect(wstring._string.length).toEqual(4); - expect(wstring._string[1]).toEqual({ - length: 2, - startDegree: 1, - startId: { - h: 1, - site: 1, - }, - visible: false, - }); - expect(wstring._string[2]).toEqual({ - length: 1, - startDegree: 3, - startId: { - h: 3, - site: 1, - }, - visible: true, - }); - }); - - it('left edge; not right edge; no merge left; no merge right', () => { - const wstring = new WString(1, 2); // [++] - wstring.integrateDelete(1); // [-][+] - - expect(wstring._string.length).toEqual(4); - expect(wstring._string[1]).toEqual({ - length: 1, - startDegree: 1, - startId: { - h: 1, - site: 1, - }, - visible: false, - }); - expect(wstring._string[2]).toEqual({ - length: 1, - startDegree: 2, - startId: { - h: 2, - site: 1, - }, - visible: true, - }); - }); - - it('not left edge; right edge; no merge left; no merge right', () => { - const wstring = new WString(1, 2); // [++] - wstring.integrateDelete(2); // [+][-] - - expect(wstring._string.length).toEqual(4); - expect(wstring._string[1]).toEqual({ - length: 1, - startDegree: 1, - startId: { - h: 1, - site: 1, - }, - visible: true, - }); - expect(wstring._string[2]).toEqual({ - length: 1, - startDegree: 2, - startId: { - h: 2, - site: 1, - }, - visible: false, - }); - }); - - it('not left edge; right edge; no merge left; merge right', () => { - const wstring = new WString(1, 3); // [+++] - wstring.integrateDelete(3); // [++][-] - wstring.integrateDelete(2); // [+][--] - - expect(wstring._string.length).toEqual(4); - expect(wstring._string[1]).toEqual({ - length: 1, - startDegree: 1, - startId: { - h: 1, - site: 1, - }, - visible: true, - }); - expect(wstring._string[2]).toEqual({ - length: 2, - startDegree: 2, - startId: { - h: 2, - site: 1, - }, - visible: false, - }); - }); - - it('left edge; right edge; no merge left; merge right', () => { - const wstring = new WString(1, 2); // [++] - wstring.integrateDelete(2); // [+][-] - wstring.integrateDelete(1); // [--] - - expect(wstring._string.length).toEqual(3); - expect(wstring._string[1]).toEqual({ - length: 2, - startDegree: 1, - startId: { - h: 1, - site: 1, - }, - visible: false, - }); - }); - - it('left edge; right edge; merge left; no merge right', () => { - const wstring = new WString(1, 2); // [++] - wstring.integrateDelete(1); // [-][+] - wstring.integrateDelete(1); // [--] - - expect(wstring._string.length).toEqual(3); - expect(wstring._string[1]).toEqual({ - length: 2, - startDegree: 1, - startId: { - h: 1, - site: 1, - }, - visible: false, - }); - }); - - it('left edge; right edge; no merge left; no merge right', () => { - const wstring = new WString(1, 1); // [+] - wstring.integrateDelete(1); // [-] - - expect(wstring._string.length).toEqual(3); - expect(wstring._string[1]).toEqual({ - length: 1, - startDegree: 1, - startId: { - h: 1, - site: 1, - }, - visible: false, - }); - }); - }); - - describe('pos', () => { - it('should work', () => { - const wstring = new WString(1); - const wchar1 = {startId: {site: 1, h: 1}, visible: true, startDegree: 1, length: 1}; - const wchar2 = {startId: {site: 1, h: 2}, visible: true, startDegree: 2, length: 1}; - const wchar3 = {startId: {site: 1, h: 3}, visible: true, startDegree: 3, length: 1}; - const wchar4 = {startId: {site: 1, h: 4}, visible: true, startDegree: 4, length: 1}; - - wstring.insert(1, wchar1); // [1] - wstring.insert(1, wchar2); // [2][1] - wstring.insert(2, wchar3); // [23][1] - wstring.insert(3, wchar4); // [234][1] - wstring.integrateDelete(1); // [-2][34][1] - - expect(wstring.pos(wstring.charFromRun(wchar1, 0), true)).toEqual(3); - expect(wstring.pos(wstring.charFromRun(wchar2, 0), true)).toEqual(-1); - expect(wstring.pos(wstring.charFromRun(wchar2, 0), /* visibleOnly */ false)).toEqual(1); - expect(wstring.pos(wstring.charFromRun(wchar3, 0), true)).toEqual(1); - expect(wstring.pos(wstring.charFromRun(wchar4, 0), true)).toEqual(2); - }); - }); - - describe('ith', () => { - it('should work', () => { - const wstring = new WString(1, 4); - - expect(wstring.ith(0)).toEqual({id: {site: -1, h: 0}, visible: true, degree: 0}); - expect(wstring.ith(1)).toEqual({id: {site: 1, h: 1}, visible: true, degree: 1}); - expect(wstring.ith(2)).toEqual({id: {site: 1, h: 2}, visible: true, degree: 2}); - expect(wstring.ith(3)).toEqual({id: {site: 1, h: 3}, visible: true, degree: 3}); - expect(wstring.ith(4)).toEqual({id: {site: 1, h: 4}, visible: true, degree: 4}); - expect(wstring.ith(5)).toEqual({id: {site: -1, h: 1}, visible: true, degree: 0}); - }); - }); - - describe('subseq', () => { - it('should work', () => { - const wstring = new WString(1, 4); - - expect(wstring.subseq(wstring.ith(1), wstring.ith(4))).toEqual([ - { - id: { - site: 1, - h: 2, - }, - visible: true, - degree: 2, - }, { - id: { - site: 1, - h: 3, - }, - visible: true, - degree: 3, - }, - ]); - }); - }); - - describe('genInsert', () => { - it('should work with single characters', () => { - const wstring = new WString(1); - - wstring.genInsert(0, 't'); - wstring.genInsert(0, 'e'); - wstring.genInsert(2, 's'); - - expect(wstring._string[1]).toEqual({ - startId: { - site: 1, - h: 2, - }, - visible: true, - length: 1, - startDegree: 2, - }); - - expect(wstring._string[2]).toEqual({ - startId: { - site: 1, - h: 1, - }, - visible: true, - length: 1, - startDegree: 1, - }); - expect(wstring._string[3]).toEqual({ - startId: { - site: 1, - h: 3, - }, - visible: true, - length: 1, - startDegree: 2, - }); - }); - - it('should work with multiple characters', () => { - const wstring = new WString(1); - - expect(wstring.genInsert(0, 'test')).toEqual({ - type: 'INS', - char: { - startId: { - site: 1, - h: 1, - }, - length: 4, - startDegree: 1, - visible: true, - }, - prev: { - id: { - site: -1, - h: 0, - }, - visible: true, - degree: 0, - }, - next: { - id: { - site: -1, - h: 1, - }, - visible: true, - degree: 0, - }, - text: 'test', - }); - - expect(wstring._string[1]).toEqual({ - startId: { - site: 1, - h: 1, - }, - visible: true, - length: 4, - startDegree: 1, - }); - }); - }); - - describe('genDelete', () => { - it('should delete range', () => { - const wstring = new WString(1, 4); // 1-4 - wstring.genDelete(0, 4); - - expect(wstring._string.length).toEqual(3); - expect(wstring._string[1]).toEqual({ - length: 4, - startDegree: 1, - startId: { - h: 1, - site: 1, - }, - visible: false, - }); - }); - - it('should merge left', () => { - const wstring = new WString(1, 4); // 1-4 - wstring.genDelete(0); - wstring.genDelete(0); - wstring.genDelete(0); - wstring.genDelete(0); - - expect(wstring._string.length).toEqual(3); - expect(wstring._string[1]).toEqual({ - length: 4, - startDegree: 1, - startId: { - h: 1, - site: 1, - }, - visible: false, - }); - }); - - it('should merge right', () => { - const wstring = new WString(1, 4); // 1-4 - - wstring.genDelete(3); - wstring.genDelete(2); - wstring.genDelete(1); - wstring.genDelete(0); - - expect(wstring._string.length).toEqual(3); - expect(wstring._string[1]).toEqual({ - length: 4, - startDegree: 1, - startId: { - h: 1, - site: 1, - }, - visible: false, - }); - }); - - it('should merge left and right', () => { - const wstring = new WString(1, 4); // 1-4 - - wstring.genDelete(3); - wstring.genDelete(0); - wstring.genDelete(1); - wstring.genDelete(0); - - expect(wstring._string.length).toEqual(3); - expect(wstring._string[1]).toEqual({ - length: 4, - startDegree: 1, - startId: { - h: 1, - site: 1, - }, - visible: false, - }); - }); - }); - - describe('visibleRanges', () => { - it('works', () => { - const wstring = new WString(1); - const wstring2 = new WString(1); - - wstring.genInsert(0, 'a'); - wstring.genInsert(1, 'a'); - wstring.genInsert(2, 'asdf'); - wstring2.genInsert(0, 'a'); - wstring2.genInsert(1, 'a'); - wstring2.genInsert(2, 'asdf'); - const op = wstring.genDelete(0, 6); - wstring2.genInsert(2, 'a'); - - invariant(op.runs != null); - expect(wstring2.visibleRanges(op.runs)).toEqual([ - { - pos: 1, - count: 2, - }, - { - pos: 4, - count: 4, - }, - ]); - }); - }); - - describe('receive', () => { - it('should report correct changes', () => { - const wstring = new WString(1); - const wstring2 = new WString(2); - - wstring2.receive(wstring.genInsert(0, 'text')); // both strings 'text' - wstring2.receive(wstring.genDelete(2)); // both strings 'tet' - const changes = wstring2.receive(wstring.genInsert(2, 's')); // both strings 'test' - - expect(changes).toEqual([{ - addition: { - pos: 3, - text: 's', - }, - }]); - }); - - it('should work with conflicting add/remove', () => { - const wstring = new WString(1); - const wstring2 = new WString(2); - - wstring2.receive(wstring.genInsert(0, 'text')); - - const op1 = wstring2.genInsert(1, 't'); - const op2 = wstring.genDelete(1, 2); - - wstring.receive(op1); - wstring2.receive(op2); - - expect(wstring2._string).toEqual(wstring._string); - }); - - it('should work with conflicting remove/remove', () => { - const wstring = new WString(1); - const wstring2 = new WString(2); - - wstring2.receive(wstring.genInsert(0, 'text')); - - const op1 = wstring2.genDelete(0, 4); - const op2 = wstring.genDelete(0, 2); - - wstring.receive(op1); - wstring2.receive(op2); - - expect(wstring2._string).toEqual(wstring._string); - }); - - it('should work with conflicting add/add', () => { - const wstring = new WString(1); - const wstring2 = new WString(2); - - wstring2.receive(JSON.parse(JSON.stringify(wstring.genInsert(0, 'text')))); - - expect(wstring2._string).toEqual(wstring._string); - - const op1 = wstring2.genInsert(0, '1'); - const op2 = wstring.genInsert(0, '2'); - - wstring.receive(op1); - wstring2.receive(op2); - - expect(wstring2._string).toEqual(wstring._string); - }); - - it('should allow out of order delete', () => { - const wstring = new WString(1); - const wstring2 = new WString(2); - - const insertTextOp = wstring.genInsert(0, 'text'); - const deleteTextOp = wstring.genDelete(0, 4); - - const changesAfterDelete = wstring2.receive(deleteTextOp); - const changesAfterInsert = wstring2.receive(insertTextOp); - - expect(changesAfterDelete.length).toEqual(0); - expect(changesAfterInsert.length).toEqual(2); - expect(wstring2._string).toEqual(wstring._string); - }); - - it('should allow out of order insert', () => { - const wstring = new WString(1); - const wstring2 = new WString(2); - - const insertTextOp = wstring.genInsert(0, 'text'); - const insertAsdfOp = wstring.genInsert(4, 'asdf'); - - const changesAfterAsdf = wstring2.receive(insertAsdfOp); - const changesAfterText = wstring2.receive(insertTextOp); - - expect(changesAfterAsdf.length).toEqual(0); - expect(changesAfterText.length).toEqual(2); - expect(wstring2._string).toEqual(wstring._string); - }); - }); -}); diff --git a/pkg/commons-node/spec/xfetch-spec.js b/pkg/commons-node/spec/xfetch-spec.js deleted file mode 100644 index 5cbf7aa9f9..0000000000 --- a/pkg/commons-node/spec/xfetch-spec.js +++ /dev/null @@ -1,89 +0,0 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the license found in the LICENSE file in - * the root directory of this source tree. - * - * @flow - */ - -import invariant from 'assert'; -import fs from 'fs'; -import fsPromise from '../../commons-node/fsPromise'; -import http from 'http'; -import xfetch from '../../commons-node/xfetch'; - -describe('xfetch', () => { - it('is the correct module', () => { - if (typeof atom === 'undefined') { - expect(xfetch).toBe(require('node-fetch')); - } else { - expect(xfetch).toBe(global.fetch); - } - }); - - it('rejects a connection error', () => { - waitsForPromise(async () => { - let errorThrown; - try { - await xfetch('http://0.0.0.0:62222'); - } catch (err) { - errorThrown = err; - } - if (typeof atom === 'undefined') { - expect(errorThrown).toMatch(/FetchError/); - } else { - expect(errorThrown).toMatch(/Failed to fetch/); - } - }); - }); - - describe('with a connection', () => { - let server: ?http.Server; - let port; - - beforeEach(() => { - server = http.createServer((req, res) => { - fs.readFile(req.url, 'utf8', (err, contents) => { - if (err) { - res.statusCode = 404; - res.end('Not found', 'utf8'); - } else { - res.setHeader('Content-Type', 'text/plain;charset=utf8'); - res.end(contents, 'utf8'); - } - }); - }).listen(0); - port = server.address().port; - }); - - afterEach(() => { - invariant(server); - server.close(); - }); - - it('can do a 2xx GET request', () => { - waitsForPromise(async () => { - const realFilename = __filename; - const response = await xfetch(`http://0.0.0.0:${port}${realFilename}`); - expect(response.ok).toBe(true); - - const text = await response.text(); - const contents = await fsPromise.readFile(realFilename, 'utf8'); - expect(text).toEqual(contents); - }); - }); - - it('can do a 404 GET request', () => { - waitsForPromise(async () => { - // eslint-disable-next-line no-path-concat - const nonexistingFilename = __filename + 'XXX'; - const response = await xfetch(`http://0.0.0.0:${port}${nonexistingFilename}`); - expect(response.ok).toBe(false); - expect(response.status).toBe(404); - expect(response.statusText).toBe('Not Found'); - }); - }); - }); -}); diff --git a/pkg/commons-node/stream.js b/pkg/commons-node/stream.js index 8fa6a350fc..eec0c5466b 100644 --- a/pkg/commons-node/stream.js +++ b/pkg/commons-node/stream.js @@ -1,26 +1,29 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the license found in the LICENSE file in - * the root directory of this source tree. - * - * @flow - */ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.observeStream = observeStream; +exports.observeRawStream = observeRawStream; -import {Observable} from 'rxjs'; +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js'); /** * Observe a stream like stdout or stderr. */ -export function observeStream(stream: stream$Readable): Observable { +function observeStream(stream) { return observeRawStream(stream).map(data => data.toString()); -} +} /** + * Copyright (c) 2015-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the license found in the LICENSE file in + * the root directory of this source tree. + * + * + */ -export function observeRawStream(stream: stream$Readable): Observable { - const error = Observable.fromEvent(stream, 'error').flatMap(Observable.throw); - return Observable - .fromEvent(stream, 'data') - .merge(error) - .takeUntil(Observable.fromEvent(stream, 'end')); -} +function observeRawStream(stream) { + const error = _rxjsBundlesRxMinJs.Observable.fromEvent(stream, 'error').flatMap(_rxjsBundlesRxMinJs.Observable.throw); + return _rxjsBundlesRxMinJs.Observable.fromEvent(stream, 'data').merge(error).takeUntil(_rxjsBundlesRxMinJs.Observable.fromEvent(stream, 'end')); +} \ No newline at end of file diff --git a/pkg/commons-node/string.js b/pkg/commons-node/string.js index 4b6c59dfea..06e2b22c47 100644 --- a/pkg/commons-node/string.js +++ b/pkg/commons-node/string.js @@ -1,3 +1,23 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.stringifyError = stringifyError; +exports.maybeToString = maybeToString; +exports.relativeDate = relativeDate; +exports.countOccurrences = countOccurrences; +exports.shellParse = shellParse; +exports.removeCommonPrefix = removeCommonPrefix; +exports.removeCommonSuffix = removeCommonSuffix; +exports.shorten = shorten; + +var _shellQuote; + +function _load_shellQuote() { + return _shellQuote = require('shell-quote'); +} + /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,19 +25,16 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * */ -import invariant from 'assert'; -import {parse} from 'shell-quote'; - -export function stringifyError(error: Error): string { +function stringifyError(error) { return `name: ${error.name}, message: ${error.message}, stack: ${error.stack}.`; } // As of Flow v0.28, Flow does not alllow implicit string coercion of null or undefined. Use this to // make it explicit. -export function maybeToString(str: ?string): string { +function maybeToString(str) { // We don't want to encourage the use of this function directly because it coerces anything to a // string. We get stricter typechecking by using maybeToString, so it should generally be // preferred. @@ -36,43 +53,11 @@ const WEEK = 7 * DAY; const YEAR = DAY * 365; const MONTH = YEAR / 12; -const shortFormats = [ - [0.7 * MINUTE, 'now'], - [1.5 * MINUTE, '1m'], - [60 * MINUTE, 'm', MINUTE], - [1.5 * HOUR, '1h'], - [DAY, 'h', HOUR], - [2 * DAY, '1d'], - [7 * DAY, 'd', DAY], - [1.5 * WEEK, '1w'], - [MONTH, 'w', WEEK], - [1.5 * MONTH, '1mo'], - [YEAR, 'mo', MONTH], - [1.5 * YEAR, '1y'], - [Number.MAX_VALUE, 'y', YEAR], -]; - -const longFormats = [ - [0.7 * MINUTE, 'just now'], - [1.5 * MINUTE, 'a minute ago'], - [60 * MINUTE, 'minutes ago', MINUTE], - [1.5 * HOUR, 'an hour ago'], - [DAY, 'hours ago', HOUR], - [2 * DAY, 'yesterday'], - [7 * DAY, 'days ago', DAY], - [1.5 * WEEK, 'a week ago'], - [MONTH, 'weeks ago', WEEK], - [1.5 * MONTH, 'a month ago'], - [YEAR, 'months ago', MONTH], - [1.5 * YEAR, 'a year ago'], - [Number.MAX_VALUE, 'years ago', YEAR], -]; - -export function relativeDate( - input_: number | Date, - reference_?: number | Date, - useShortVariant?: boolean = false, -): string { +const shortFormats = [[0.7 * MINUTE, 'now'], [1.5 * MINUTE, '1m'], [60 * MINUTE, 'm', MINUTE], [1.5 * HOUR, '1h'], [DAY, 'h', HOUR], [2 * DAY, '1d'], [7 * DAY, 'd', DAY], [1.5 * WEEK, '1w'], [MONTH, 'w', WEEK], [1.5 * MONTH, '1mo'], [YEAR, 'mo', MONTH], [1.5 * YEAR, '1y'], [Number.MAX_VALUE, 'y', YEAR]]; + +const longFormats = [[0.7 * MINUTE, 'just now'], [1.5 * MINUTE, 'a minute ago'], [60 * MINUTE, 'minutes ago', MINUTE], [1.5 * HOUR, 'an hour ago'], [DAY, 'hours ago', HOUR], [2 * DAY, 'yesterday'], [7 * DAY, 'days ago', DAY], [1.5 * WEEK, 'a week ago'], [MONTH, 'weeks ago', WEEK], [1.5 * MONTH, 'a month ago'], [YEAR, 'months ago', MONTH], [1.5 * YEAR, 'a year ago'], [Number.MAX_VALUE, 'years ago', YEAR]]; + +function relativeDate(input_, reference_, useShortVariant = false) { let input = input_; let reference = reference_; if (input instanceof Date) { @@ -104,8 +89,10 @@ export function relativeDate( * Count the number of occurrences of `char` in `str`. * `char` must be a string of length 1. */ -export function countOccurrences(haystack: string, char: string) { - invariant(char.length === 1, 'char must be a string of length 1'); +function countOccurrences(haystack, char) { + if (!(char.length === 1)) { + throw new Error('char must be a string of length 1'); + } let count = 0; const code = char.charCodeAt(0); @@ -121,8 +108,8 @@ export function countOccurrences(haystack: string, char: string) { * shell-quote's parse allows pipe operators. * Generally users don't care about this, so throw if we encounter any operators. */ -export function shellParse(str: string, env?: Object): Array { - const result = parse(str, env); +function shellParse(str, env) { + const result = (0, (_shellQuote || _load_shellQuote()).parse)(str, env); for (let i = 0; i < result.length; i++) { if (typeof result[i] !== 'string') { throw new Error(`Unexpected operator "${result[i].op}" provided to shellParse`); @@ -131,7 +118,7 @@ export function shellParse(str: string, env?: Object): Array { return result; } -export function removeCommonPrefix(a: string, b: string): [string, string] { +function removeCommonPrefix(a, b) { let i = 0; while (a[i] === b[i] && i < a.length && i < b.length) { i++; @@ -139,7 +126,7 @@ export function removeCommonPrefix(a: string, b: string): [string, string] { return [a.substring(i), b.substring(i)]; } -export function removeCommonSuffix(a: string, b: string): [string, string] { +function removeCommonSuffix(a, b) { let i = 0; while (a[a.length - 1 - i] === b[b.length - 1 - i] && i < a.length && i < b.length) { i++; @@ -147,6 +134,6 @@ export function removeCommonSuffix(a: string, b: string): [string, string] { return [a.substring(0, a.length - i), b.substring(0, b.length - i)]; } -export function shorten(str: string, maxLength: number, suffix?: string): string { +function shorten(str, maxLength, suffix) { return str.length < maxLength ? str : str.slice(0, maxLength) + (suffix || ''); -} +} \ No newline at end of file diff --git a/pkg/commons-node/system-info.js b/pkg/commons-node/system-info.js index 61293e0792..6fd4b443db 100644 --- a/pkg/commons-node/system-info.js +++ b/pkg/commons-node/system-info.js @@ -1,3 +1,37 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.isRunningInTest = exports.OS_TYPE = undefined; +exports.isRunningInClient = isRunningInClient; +exports.getAtomNuclideDir = getAtomNuclideDir; +exports.getAtomVersion = getAtomVersion; +exports.getNuclideVersion = getNuclideVersion; +exports.getNuclideRealDir = getNuclideRealDir; +exports.getOsType = getOsType; +exports.isRunningInWindows = isRunningInWindows; +exports.getOsVersion = getOsVersion; +exports.getRuntimePath = getRuntimePath; + +var _fs = _interopRequireDefault(require('fs')); + +var _once; + +function _load_once() { + return _once = _interopRequireDefault(require('./once')); +} + +var _os = _interopRequireDefault(require('os')); + +var _nuclideUri; + +function _load_nuclideUri() { + return _nuclideUri = _interopRequireDefault(require('./nuclideUri')); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,25 +39,19 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * */ -import fs from 'fs'; -import invariant from 'assert'; -import once from './once'; -import os from 'os'; -import nuclideUri from './nuclideUri'; - const NUCLIDE_PACKAGE_JSON_PATH = require.resolve('../../package.json'); -const NUCLIDE_BASEDIR = nuclideUri.dirname(NUCLIDE_PACKAGE_JSON_PATH); +const NUCLIDE_BASEDIR = (_nuclideUri || _load_nuclideUri()).default.dirname(NUCLIDE_PACKAGE_JSON_PATH); -const pkgJson = JSON.parse(fs.readFileSync(NUCLIDE_PACKAGE_JSON_PATH, 'utf8')); +const pkgJson = JSON.parse(_fs.default.readFileSync(NUCLIDE_PACKAGE_JSON_PATH, 'utf8')); -export const OS_TYPE = { +const OS_TYPE = exports.OS_TYPE = { WIN32: 'win32', WIN64: 'win64', LINUX: 'linux', - OSX: 'darwin', + OSX: 'darwin' }; // Prior to Atom v1.7.0, `atom.inSpecMode` had a chance of performing an IPC call that could be @@ -34,7 +62,7 @@ export const OS_TYPE = { // ensures happens only once. // // [1]: https://github.com/atom/atom/blob/v1.6.2/src/window-load-settings-helpers.coffee#L10-L14 -export const isRunningInTest = once((): boolean => { +const isRunningInTest = exports.isRunningInTest = (0, (_once || _load_once()).default)(() => { if (isRunningInClient()) { return atom.inSpecMode(); } else { @@ -42,48 +70,52 @@ export const isRunningInTest = once((): boolean => { } }); -export function isRunningInClient(): boolean { +function isRunningInClient() { return typeof atom !== 'undefined'; } // This path may be a symlink. -export function getAtomNuclideDir(): string { +function getAtomNuclideDir() { if (!isRunningInClient()) { throw Error('Not running in Atom.'); } const nuclidePackageModule = atom.packages.getLoadedPackage('nuclide'); - invariant(nuclidePackageModule); + + if (!nuclidePackageModule) { + throw new Error('Invariant violation: "nuclidePackageModule"'); + } + return nuclidePackageModule.path; } -export function getAtomVersion(): string { +function getAtomVersion() { if (!isRunningInClient()) { throw Error('Not running in Atom.'); } return atom.getVersion(); } -export function getNuclideVersion(): string { +function getNuclideVersion() { return pkgJson.version; } -export function getNuclideRealDir(): string { +function getNuclideRealDir() { return NUCLIDE_BASEDIR; } -export function getOsType(): string { - return os.platform(); +function getOsType() { + return _os.default.platform(); } -export function isRunningInWindows(): boolean { +function isRunningInWindows() { return getOsType() === OS_TYPE.WIN32 || getOsType() === OS_TYPE.WIN64; } -export function getOsVersion(): string { - return os.release(); +function getOsVersion() { + return _os.default.release(); } -export function getRuntimePath(): string { +function getRuntimePath() { // "resourcesPath" only exists in Atom. It's as close as you can get to // Atom's path. In the general case, it looks like this: // Mac: "/Applications/Atom.app/Contents/Resources" @@ -92,9 +124,9 @@ export function getRuntimePath(): string { // "C:\Atom\resources" if (global.atom && typeof process.resourcesPath === 'string') { const resourcesPath = process.resourcesPath; - if (os.platform() === 'darwin') { + if (_os.default.platform() === 'darwin') { return resourcesPath.replace(/\/Contents\/Resources$/, ''); - } else if (os.platform() === 'linux') { + } else if (_os.default.platform() === 'linux') { return resourcesPath.replace(/\/resources$/, ''); } else { return resourcesPath.replace(/[\\]+resources$/, ''); @@ -102,4 +134,4 @@ export function getRuntimePath(): string { } else { return process.execPath; } -} +} \ No newline at end of file diff --git a/pkg/commons-node/tasks.js b/pkg/commons-node/tasks.js index 6036b6c741..204aa5baac 100644 --- a/pkg/commons-node/tasks.js +++ b/pkg/commons-node/tasks.js @@ -1,99 +1,99 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the license found in the LICENSE file in - * the root directory of this source tree. - * - * @flow - */ +'use strict'; -// It's really convenient to model processes with Observables but Atom use a more OO [Task -// interface](https://atom.io/docs/api/latest/Task). These are utilities for converting between the -// two. +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.taskFromObservable = taskFromObservable; +exports.observableFromTask = observableFromTask; -import UniversalDisposable from './UniversalDisposable'; -import {observableFromSubscribeFunction} from './event'; -import invariant from 'assert'; -import {Observable, Subscription} from 'rxjs'; +var _UniversalDisposable; -// FIXME: This should really be an interface, but we're currently transpiling with Babel 5, which -// doesn't support that. -export type Task = { - start: () => void, - cancel: () => void, - onDidComplete: (callback: () => mixed) => IDisposable, - onDidError: (callback: (err: Error) => mixed) => IDisposable, - onProgress?: (callback: (progress: ?number) => mixed) => IDisposable, -}; - -type ProgressEvent = { - type: 'progress', - progress: ?number, -}; +function _load_UniversalDisposable() { + return _UniversalDisposable = _interopRequireDefault(require('./UniversalDisposable')); +} -// Currently, there's only one type of task event (for progress), but there may be more in the -// future. -export type TaskEvent = ProgressEvent; +var _event; + +function _load_event() { + return _event = require('./event'); +} + +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js'); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /** * Subscribe to an observable and transform it into the Task interface. The Task interface allows us * to interop nicely with Atom and Atom packages without forcing them to use Rx, but internally, * Observables are probably how we'll always build the functionality. */ -export function taskFromObservable(observable: Observable): Task { + + +// FIXME: This should really be an interface, but we're currently transpiling with Babel 5, which +// doesn't support that. + + +// Currently, there's only one type of task event (for progress), but there may be more in the +// future. +function taskFromObservable(observable) { const events = observable.share().publish(); let subscription; return { - start(): void { + start() { if (subscription == null) { subscription = events.connect(); } }, - cancel(): void { + cancel() { if (subscription != null) { subscription.unsubscribe(); } }, - onDidComplete(callback: () => mixed): IDisposable { - return new UniversalDisposable( - events.subscribe({complete: callback, error: () => {}}), - ); - }, - onDidError(callback: (err: Error) => mixed): IDisposable { - return new UniversalDisposable(events.subscribe({error: callback})); + onDidComplete(callback) { + return new (_UniversalDisposable || _load_UniversalDisposable()).default(events.subscribe({ complete: callback, error: () => {} })); }, - onProgress(callback: (progress: ?number) => mixed): IDisposable { - return new UniversalDisposable( - events - .filter(event => event.type === 'progress') - .map(event => { - invariant(event.type === 'progress'); - return event.progress; - }) - .subscribe({next: callback, error: () => {}}), - ); + onDidError(callback) { + return new (_UniversalDisposable || _load_UniversalDisposable()).default(events.subscribe({ error: callback })); }, + onProgress(callback) { + return new (_UniversalDisposable || _load_UniversalDisposable()).default(events.filter(event => event.type === 'progress').map(event => { + if (!(event.type === 'progress')) { + throw new Error('Invariant violation: "event.type === \'progress\'"'); + } + + return event.progress; + }).subscribe({ next: callback, error: () => {} })); + } }; } /** * Convert a task to an observable of events. */ -export function observableFromTask(task: Task): Observable { - return Observable.create(observer => { +/** + * Copyright (c) 2015-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the license found in the LICENSE file in + * the root directory of this source tree. + * + * + */ + +// It's really convenient to model processes with Observables but Atom use a more OO [Task +// interface](https://atom.io/docs/api/latest/Task). These are utilities for converting between the +// two. + +function observableFromTask(task) { + return _rxjsBundlesRxMinJs.Observable.create(observer => { let finished = false; - const events = typeof task.onProgress === 'function' - ? observableFromSubscribeFunction(task.onProgress.bind(task)) - .map(progress => ({type: 'progress', progress})) - : Observable.never(); - const completeEvents = observableFromSubscribeFunction(task.onDidComplete.bind(task)); - const errors = observableFromSubscribeFunction(task.onDidError.bind(task)) - .switchMap(Observable.throw); + const events = typeof task.onProgress === 'function' ? (0, (_event || _load_event()).observableFromSubscribeFunction)(task.onProgress.bind(task)).map(progress => ({ type: 'progress', progress })) : _rxjsBundlesRxMinJs.Observable.never(); + const completeEvents = (0, (_event || _load_event()).observableFromSubscribeFunction)(task.onDidComplete.bind(task)); + const errors = (0, (_event || _load_event()).observableFromSubscribeFunction)(task.onDidError.bind(task)).switchMap(_rxjsBundlesRxMinJs.Observable.throw); - const subscription = new Subscription(); + const subscription = new _rxjsBundlesRxMinJs.Subscription(); subscription.add(() => { if (!finished) { @@ -101,18 +101,17 @@ export function observableFromTask(task: Task): Observable { } }); - subscription.add( - Observable.merge(events, errors) - .takeUntil(completeEvents) - .do({ - complete: () => { finished = true; }, - error: () => { finished = true; }, - }) - .subscribe(observer), - ); + subscription.add(_rxjsBundlesRxMinJs.Observable.merge(events, errors).takeUntil(completeEvents).do({ + complete: () => { + finished = true; + }, + error: () => { + finished = true; + } + }).subscribe(observer)); task.start(); return subscription; }); -} +} \ No newline at end of file diff --git a/pkg/commons-node/tokenizedText-rpc-types.js b/pkg/commons-node/tokenizedText-rpc-types.js index 981ef203c1..a726efc43f 100644 --- a/pkg/commons-node/tokenizedText-rpc-types.js +++ b/pkg/commons-node/tokenizedText-rpc-types.js @@ -1,29 +1 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the license found in the LICENSE file in - * the root directory of this source tree. - * - * @flow - */ - -// Separated out for RPC usage. - -export type TokenKind = 'keyword' - | 'class-name' - | 'constructor' - | 'method' - | 'param' - | 'string' - | 'whitespace' - | 'plain' - | 'type' - ; - -export type TextToken = { - kind: TokenKind, - value: string, -}; - -export type TokenizedText = Array; +'use strict'; \ No newline at end of file diff --git a/pkg/commons-node/tokenizedText.js b/pkg/commons-node/tokenizedText.js index bac9d23144..54dee52eb7 100644 --- a/pkg/commons-node/tokenizedText.js +++ b/pkg/commons-node/tokenizedText.js @@ -1,55 +1,61 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the license found in the LICENSE file in - * the root directory of this source tree. - * - * @flow - */ - -import type { - TokenKind, - TextToken, -} from './tokenizedText-rpc-types'; - -export function keyword(value: string): TextToken { +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.keyword = keyword; +exports.className = className; +exports.constructor = constructor; +exports.method = method; +exports.param = param; +exports.string = string; +exports.whitespace = whitespace; +exports.plain = plain; +exports.type = type; +function keyword(value) { return _buildToken('keyword', value); -} - -export function className(value: string): TextToken { +} /** + * Copyright (c) 2015-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the license found in the LICENSE file in + * the root directory of this source tree. + * + * + */ + +function className(value) { return _buildToken('class-name', value); } -export function constructor(value: string): TextToken { +function constructor(value) { return _buildToken('constructor', value); } -export function method(value: string): TextToken { +function method(value) { return _buildToken('method', value); } -export function param(value: string): TextToken { +function param(value) { return _buildToken('param', value); } -export function string(value: string): TextToken { +function string(value) { return _buildToken('string', value); } -export function whitespace(value: string): TextToken { +function whitespace(value) { return _buildToken('whitespace', value); } -export function plain(value: string): TextToken { +function plain(value) { return _buildToken('plain', value); } -export function type(value: string): TextToken { +function type(value) { return _buildToken('type', value); } - -function _buildToken(kind: TokenKind, value: string): TextToken { - return {kind, value}; -} +function _buildToken(kind, value) { + return { kind, value }; +} \ No newline at end of file diff --git a/pkg/commons-node/which.js b/pkg/commons-node/which.js index a51492f59e..b6aad4167e 100644 --- a/pkg/commons-node/which.js +++ b/pkg/commons-node/which.js @@ -1,3 +1,28 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.__BABEL_CJS_COMPAT__ = undefined; + +var _asyncToGenerator = _interopRequireDefault(require('async-to-generator')); + +var _process; + +function _load_process() { + return _process = require('./process'); +} + +var _os = _interopRequireDefault(require('os')); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/** + * Provides a cross-platform way to check whether a binary is available. + * + * We ran into problems with the npm `which` package (the nature of which I unfortunately don't + * remember) so we can use this for now. + */ /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,27 +30,28 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * */ -import {checkOutput} from './process'; -import os from 'os'; +exports.default = (() => { + var _ref = (0, _asyncToGenerator.default)(function* (command) { + const whichCommand = process.platform === 'win32' ? 'where' : 'which'; + try { + const result = yield (0, (_process || _load_process()).checkOutput)(whichCommand, [command]); + return result.stdout.split(_os.default.EOL)[0]; + } catch (e) { + return null; + } + }); -/** - * Provides a cross-platform way to check whether a binary is available. - * - * We ran into problems with the npm `which` package (the nature of which I unfortunately don't - * remember) so we can use this for now. - */ -export default async function which(command: string): Promise { - const whichCommand = process.platform === 'win32' ? 'where' : 'which'; - try { - const result = await checkOutput(whichCommand, [command]); - return result.stdout.split(os.EOL)[0]; - } catch (e) { - return null; + function which(_x) { + return _ref.apply(this, arguments); } -} + + return which; +})(); // Fake export to avoid babel's commonjs compat -export const __BABEL_CJS_COMPAT__ = {}; + + +const __BABEL_CJS_COMPAT__ = exports.__BABEL_CJS_COMPAT__ = {}; \ No newline at end of file diff --git a/pkg/commons-node/wootr.js b/pkg/commons-node/wootr.js index 9dea57cd3e..40cb1ce3cd 100644 --- a/pkg/commons-node/wootr.js +++ b/pkg/commons-node/wootr.js @@ -1,88 +1,46 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the license found in the LICENSE file in - * the root directory of this source tree. - * - * @flow - */ - -import invariant from 'assert'; - -export type WId = { - site: number, - h: number, -}; - -export type WChar = { - id: WId, - visible: boolean, - degree: number, -}; +'use strict'; -export type WCharRun = { - startId: WId, - visible: boolean, - startDegree: number, - length: number, -}; +Object.defineProperty(exports, "__esModule", { + value: true +}); -export type WOpType = 'INS' | 'DEL'; - -export type WOp = { - type: WOpType, - text?: string, - char?: WCharRun, - runs?: Array, - next?: WChar, - prev?: WChar, -}; // Represents a concrete change to a string. That is, the result of applying // the WOp to the local string. -export type WChange = { - addition?: {pos: number, text: string}, - removals?: Array<{pos: number, count: number}>, -}; - -function idLess(idLeft: WId, idRight: WId): boolean { - return (idLeft.site < idRight.site - || (idLeft.site === idRight.site && idLeft.h < idRight.h)); -} +function idLess(idLeft, idRight) { + return idLeft.site < idRight.site || idLeft.site === idRight.site && idLeft.h < idRight.h; +} /** + * Copyright (c) 2015-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the license found in the LICENSE file in + * the root directory of this source tree. + * + * + */ -export class WString { - static start: WCharRun; - static end: WCharRun; - _siteId: number; - _localId: number; - _string: Array; - _ops: Array; +class WString { - constructor(siteId: number, length: number = 0) { + constructor(siteId, length = 0) { this._siteId = siteId; this._localId = 1; this._string = [WString.start, WString.end]; this._ops = []; if (length > 0) { this._localId = length; - this.insert( - 1, - { - startId: { - site: siteId, - h: 1, - }, - visible: true, - startDegree: 1, - length, + this.insert(1, { + startId: { + site: siteId, + h: 1 }, - length, - ); + visible: true, + startDegree: 1, + length + }, length); } } - insert(pos: number, c: WCharRun) { + insert(pos, c) { // Find the run that has the previous position in it. let leftHalfIndex; let offset = pos; @@ -119,43 +77,32 @@ export class WString { // [begin][id:1,1; len: 4, vis: 1;]*<= insert inside there*[end] // => // [begin][id:1,1; len: 2, vis: 1;][id:1,4; len: 1, vis: 1;][id:1,3; len: 2, vis: 1;][end] - if (leftHalf.startId.site === c.startId.site - && leftHalf.startId.h === c.startId.h - leftHalf.length - && offset === leftHalf.length - && c.visible === leftHalf.visible) { + if (leftHalf.startId.site === c.startId.site && leftHalf.startId.h === c.startId.h - leftHalf.length && offset === leftHalf.length && c.visible === leftHalf.visible) { leftHalf.length += c.length; } else if (offset === leftHalf.length) { - this._string.splice( - leftHalfIndex + 1, - 0, - c, - ); + this._string.splice(leftHalfIndex + 1, 0, c); } else { const rightHalf = { startId: { site: leftHalf.startId.site, - h: leftHalf.startId.h + offset, + h: leftHalf.startId.h + offset }, visible: leftHalf.visible, length: leftHalf.length - offset, - startDegree: leftHalf.startDegree + offset, + startDegree: leftHalf.startDegree + offset }; leftHalf.length -= leftHalf.length - offset; - this._string.splice( - leftHalfIndex + 1, - 0, - c, - rightHalf, - ); + this._string.splice(leftHalfIndex + 1, 0, c, rightHalf); } } - canMergeRight(i: number): boolean { - invariant(i < this._string.length - 1); - return this._string[i].startId.site === this._string[i + 1].startId.site - && this._string[i].startId.h === this._string[i + 1].startId.h - this._string[i].length - && this._string[i].visible === this._string[i + 1].visible; + canMergeRight(i) { + if (!(i < this._string.length - 1)) { + throw new Error('Invariant violation: "i < this._string.length - 1"'); + } + + return this._string[i].startId.site === this._string[i + 1].startId.site && this._string[i].startId.h === this._string[i + 1].startId.h - this._string[i].length && this._string[i].visible === this._string[i + 1].visible; } mergeRuns() { @@ -171,7 +118,7 @@ export class WString { this._string = newString; } - integrateDelete(pos: number): void { + integrateDelete(pos) { let originalIndex; let offset = pos; @@ -193,54 +140,47 @@ export class WString { runs.push({ startId: { site: original.startId.site, - h: original.startId.h, + h: original.startId.h }, visible: original.visible, length: offset, - startDegree: original.startDegree, + startDegree: original.startDegree }); } runs.push({ startId: { site: original.startId.site, - h: original.startId.h + offset, + h: original.startId.h + offset }, visible: false, length: 1, - startDegree: original.startDegree + offset, + startDegree: original.startDegree + offset }); if (offset < original.length - 1) { runs.push({ startId: { site: original.startId.site, - h: original.startId.h + offset + 1, + h: original.startId.h + offset + 1 }, visible: original.visible, length: original.length - (offset + 1), - startDegree: original.startDegree + offset + 1, + startDegree: original.startDegree + offset + 1 }); } - this._string.splice( - originalIndex, - 1, - ...runs, - ); + this._string.splice(originalIndex, 1, ...runs); this.mergeRuns(); } - pos(c: WChar, visibleOnly: boolean = false): number { + pos(c, visibleOnly = false) { let currentOffset = 0; for (let i = 0; i < this._string.length; i++) { const currentRun = this._string[i]; - if (currentRun.startId.site === c.id.site - && currentRun.startId.h <= c.id.h - && currentRun.startId.h + currentRun.length > c.id.h - && (!visibleOnly || this._string[i].visible)) { + if (currentRun.startId.site === c.id.site && currentRun.startId.h <= c.id.h && currentRun.startId.h + currentRun.length > c.id.h && (!visibleOnly || this._string[i].visible)) { return currentOffset + (c.id.h - currentRun.startId.h); } if (!visibleOnly || this._string[i].visible) { @@ -250,18 +190,18 @@ export class WString { return -1; } - charFromRun(run: WCharRun, offset: number): WChar { + charFromRun(run, offset) { return { id: { site: run.startId.site, - h: run.startId.h + offset, + h: run.startId.h + offset }, degree: run.startDegree + offset, - visible: run.visible, + visible: run.visible }; } - ith(pos: number, visibleOnly: boolean = true): WChar { + ith(pos, visibleOnly = true) { let i; let offset = pos; @@ -280,7 +220,7 @@ export class WString { /** * Returns the subset (left, right) of the string sequence (exlusive on both sides) */ - subseq(left: WChar, right: WChar): Array { + subseq(left, right) { const sub = []; if (left == null || right == null) { throw new Error('asdf'); @@ -295,7 +235,7 @@ export class WString { return sub; } - genInsert(pos: number, text: string): WOp { + genInsert(pos, text) { const prevChar = this.ith(pos); const nextChar = this.ith(pos + 1); @@ -306,22 +246,22 @@ export class WString { const c = { startId: { site: this._siteId, - h: this._localId, + h: this._localId }, visible: true, startDegree: Math.max(prevChar.degree, nextChar.degree) + 1, - length: text.length, + length: text.length }; this._localId += text.length; this.integrateIns(c, prevChar, nextChar); - return {type: 'INS', char: {...c}, prev: prevChar, next: nextChar, text}; + return { type: 'INS', char: Object.assign({}, c), prev: prevChar, next: nextChar, text }; } // Main wooto algorithm. see: "Wooki: a P2P Wiki-based Collaborative Writing Tool" // returns the visible position of the string that this text is inserted into - integrateIns(c: WCharRun, cp: WChar, cn: WChar): number { + integrateIns(c, cp, cn) { // Consider the sequence of characters between cp, and cn const sub = this.subseq(cp, cn); // If this is an empty sequence just insert the character @@ -345,25 +285,23 @@ export class WString { return this.integrateIns(c, idOrderedSubset[i - 1], idOrderedSubset[i]); } - charToRun(char: WChar, visible: boolean): WCharRun { + charToRun(char, visible) { return { startId: { site: char.id.site, - h: char.id.h, + h: char.id.h }, startDegree: char.degree, visible, - length: 1, + length: 1 }; } - canExtendRun(run: WCharRun, char: WChar): boolean { - return run.startId.site === char.id.site - && run.startId.h + run.length === char.id.h - && run.startDegree + run.length === char.degree; + canExtendRun(run, char) { + return run.startId.site === char.id.site && run.startId.h + run.length === char.id.h && run.startDegree + run.length === char.degree; } - charsToRuns(chars: Array): Array { + charsToRuns(chars) { if (chars.length === 0) { return []; } @@ -385,24 +323,24 @@ export class WString { return runs; } - genDelete(pos: number, count: number = 1): WOp { + genDelete(pos, count = 1) { const chars = []; for (let i = 0; i < count; i++) { chars.push(this.ith(pos + 1)); this.integrateDelete(pos + 1); } - return {type: 'DEL', runs: this.charsToRuns(chars)}; + return { type: 'DEL', runs: this.charsToRuns(chars) }; } - visibleRanges(runs: Array): Array<{pos: number, count: number}> { + visibleRanges(runs) { let pos = -1; let count = 1; const ranges = []; for (let i = 0; i < runs.length; i++) { for (let j = 0; j < runs[i].length; j++) { const wchar = this.charFromRun(runs[i], j); - const newPos = this.pos(wchar, /* visibleOnly */ true); + const newPos = this.pos(wchar, /* visibleOnly */true); // Skip invisible characters if (newPos === -1) { continue; @@ -411,7 +349,7 @@ export class WString { count += 1; } else { if (pos > 0) { - ranges.push({pos, count}); + ranges.push({ pos, count }); } count = 1; pos = newPos; @@ -419,13 +357,13 @@ export class WString { } } if (pos > 0) { - ranges.push({pos, count}); + ranges.push({ pos, count }); } return ranges; } - applyOps(): Array { + applyOps() { const changes = []; let lastCount = this._ops.length + 1; @@ -443,9 +381,12 @@ export class WString { return changes; } - receive(op: WOp): Array { + receive(op) { if (op.type === 'INS') { - invariant(op.char != null); + if (!(op.char != null)) { + throw new Error('Invariant violation: "op.char != null"'); + } + if (this.contains(this.charFromRun(op.char, 0))) { return []; } @@ -456,15 +397,22 @@ export class WString { return this.applyOps(); } - canApplyOp(op: WOp): boolean { + canApplyOp(op) { if (op.type === 'INS') { const prev = op.prev; const next = op.next; - invariant(prev != null && next != null); + if (!(prev != null && next != null)) { + throw new Error('Invariant violation: "prev != null && next != null"'); + } + return this.contains(prev) && this.contains(next); - } else { // DEL - invariant(op.runs != null); + } else { + // DEL + if (!(op.runs != null)) { + throw new Error('Invariant violation: "op.runs != null"'); + } + for (let i = 0; i < op.runs.length; i++) { for (let j = 0; j < op.runs[i].length; j++) { if (!this.contains(this.charFromRun(op.runs[i], j))) { @@ -476,14 +424,14 @@ export class WString { } } - contains(c: WChar): boolean { + contains(c) { if (this.pos(c, false) !== -1) { return true; } return false; } - execute(op: WOp): WChange { + execute(op) { const next = op.next; const prev = op.prev; @@ -492,14 +440,15 @@ export class WString { throw new Error('INS type operation invalid.'); } - const pos = this.integrateIns( - op.char, - prev, - next, - ); - invariant(op.text); - return {addition: {pos, text: op.text}}; - } else { // DEL + const pos = this.integrateIns(op.char, prev, next); + + if (!op.text) { + throw new Error('Invariant violation: "op.text"'); + } + + return { addition: { pos, text: op.text } }; + } else { + // DEL if (op.runs == null) { throw new Error('DEL operation invalid'); } @@ -511,21 +460,22 @@ export class WString { this.integrateDelete(ranges[i].pos); } } - return {removals: ranges}; + return { removals: ranges }; } } } +exports.WString = WString; WString.start = { - startId: {site: -1, h: 0}, + startId: { site: -1, h: 0 }, visible: true, startDegree: 0, - length: 1, + length: 1 }; WString.end = { - startId: {site: -1, h: 1}, + startId: { site: -1, h: 1 }, visible: true, startDegree: 0, - length: 1, -}; + length: 1 +}; \ No newline at end of file diff --git a/pkg/commons-node/xfetch.js b/pkg/commons-node/xfetch.js index 995883524f..f74ce734b2 100644 --- a/pkg/commons-node/xfetch.js +++ b/pkg/commons-node/xfetch.js @@ -1,3 +1,8 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,7 +10,7 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * */ /** @@ -39,8 +44,5 @@ // The export is typed with `typeof fetch` so flow treats the polyfill as the // real `fetch`. -export default ( - (typeof global.fetch === 'function' - ? global.fetch - : require('node-fetch')): typeof fetch - ); +exports.default = typeof global.fetch === 'function' ? global.fetch : require('node-fetch'); +module.exports = exports['default']; \ No newline at end of file diff --git a/pkg/hyperclick/lib/Hyperclick.js b/pkg/hyperclick/lib/Hyperclick.js index 30dfbfc192..f5dfc8d3ab 100644 --- a/pkg/hyperclick/lib/Hyperclick.js +++ b/pkg/hyperclick/lib/Hyperclick.js @@ -1,3 +1,14 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _asyncToGenerator = _interopRequireDefault(require('async-to-generator')); + +/** + * Calls the given functions and returns the first non-null return value. + */ /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,58 +16,75 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * */ -import type { - HyperclickSuggestion, - HyperclickProvider, -} from './types'; - -import HyperclickForTextEditor from './HyperclickForTextEditor'; -import SuggestionList from './SuggestionList'; -import { - defaultWordRegExpForEditor, - getWordTextAndRange, -} from './hyperclick-utils'; - -import {observeTextEditors} from '../../commons-atom/text-editor'; -import {trackTiming} from '../../nuclide-analytics'; - -/** - * Calls the given functions and returns the first non-null return value. - */ -async function findTruthyReturnValue(fns: Array Promise>): Promise { - for (const fn of fns) { - // eslint-disable-next-line no-await-in-loop - const result = typeof fn === 'function' ? await fn() : null; - if (result) { - return result; +let findTruthyReturnValue = (() => { + var _ref = (0, _asyncToGenerator.default)(function* (fns) { + for (const fn of fns) { + // eslint-disable-next-line no-await-in-loop + const result = typeof fn === 'function' ? yield fn() : null; + if (result) { + return result; + } } - } -} + }); + + return function findTruthyReturnValue(_x) { + return _ref.apply(this, arguments); + }; +})(); /** * Construct this object to enable Hyperclick in the Atom workspace. * Call `dispose` to disable the feature. */ -export default class Hyperclick { - _consumedProviders: Array; - _suggestionList: SuggestionList; - _hyperclickForTextEditors: Set; - _textEditorSubscription: IDisposable; + + +var _HyperclickForTextEditor; + +function _load_HyperclickForTextEditor() { + return _HyperclickForTextEditor = _interopRequireDefault(require('./HyperclickForTextEditor')); +} + +var _SuggestionList; + +function _load_SuggestionList() { + return _SuggestionList = _interopRequireDefault(require('./SuggestionList')); +} + +var _hyperclickUtils; + +function _load_hyperclickUtils() { + return _hyperclickUtils = require('./hyperclick-utils'); +} + +var _textEditor; + +function _load_textEditor() { + return _textEditor = require('../../commons-atom/text-editor'); +} + +var _nuclideAnalytics; + +function _load_nuclideAnalytics() { + return _nuclideAnalytics = require('../../nuclide-analytics'); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +class Hyperclick { constructor() { this._consumedProviders = []; - this._suggestionList = new SuggestionList(); + this._suggestionList = new (_SuggestionList || _load_SuggestionList()).default(); this._hyperclickForTextEditors = new Set(); - this._textEditorSubscription = observeTextEditors( - this.observeTextEditor.bind(this)); + this._textEditorSubscription = (0, (_textEditor || _load_textEditor()).observeTextEditors)(this.observeTextEditor.bind(this)); } - observeTextEditor(textEditor: TextEditor) { - const hyperclickForTextEditor = new HyperclickForTextEditor(textEditor, this); + observeTextEditor(textEditor) { + const hyperclickForTextEditor = new (_HyperclickForTextEditor || _load_HyperclickForTextEditor()).default(textEditor, this); this._hyperclickForTextEditors.add(hyperclickForTextEditor); textEditor.onDidDestroy(() => { hyperclickForTextEditor.dispose(); @@ -73,7 +101,7 @@ export default class Hyperclick { this._hyperclickForTextEditors.clear(); } - _applyToAll(item: Array | T, f: (x: T) => void): void { + _applyToAll(item, f) { if (Array.isArray(item)) { item.forEach(x => f(x)); } else { @@ -81,15 +109,15 @@ export default class Hyperclick { } } - consumeProvider(provider: HyperclickProvider | Array): void { + consumeProvider(provider) { this._applyToAll(provider, singleProvider => this._consumeSingleProvider(singleProvider)); } - removeProvider(provider: HyperclickProvider | Array): void { + removeProvider(provider) { this._applyToAll(provider, singleProvider => this._removeSingleProvider(singleProvider)); } - _consumeSingleProvider(provider: HyperclickProvider): void { + _consumeSingleProvider(provider) { const priority = provider.priority || 0; for (let i = 0, len = this._consumedProviders.length; i < len; i++) { const item = this._consumedProviders[i]; @@ -109,7 +137,7 @@ export default class Hyperclick { this._consumedProviders.push(provider); } - _removeSingleProvider(provider: HyperclickProvider): void { + _removeSingleProvider(provider) { const index = this._consumedProviders.indexOf(provider); if (index >= 0) { this._consumedProviders.splice(index, 1); @@ -119,24 +147,20 @@ export default class Hyperclick { /** * Returns the first suggestion from the consumed providers. */ - getSuggestion(textEditor: TextEditor, position: atom$Point): Promise { + getSuggestion(textEditor, position) { // Get the default word RegExp for this editor. - const defaultWordRegExp = defaultWordRegExpForEditor(textEditor); + const defaultWordRegExp = (0, (_hyperclickUtils || _load_hyperclickUtils()).defaultWordRegExpForEditor)(textEditor); - return findTruthyReturnValue(this._consumedProviders.map((provider: HyperclickProvider) => { + return findTruthyReturnValue(this._consumedProviders.map(provider => { if (provider.getSuggestion) { const getSuggestion = provider.getSuggestion.bind(provider); - return () => trackTiming( - getProviderName(provider) + '.getSuggestion', - () => getSuggestion(textEditor, position)); + return () => (0, (_nuclideAnalytics || _load_nuclideAnalytics()).trackTiming)(getProviderName(provider) + '.getSuggestion', () => getSuggestion(textEditor, position)); } else if (provider.getSuggestionForWord) { const getSuggestionForWord = provider.getSuggestionForWord.bind(provider); return () => { const wordRegExp = provider.wordRegExp || defaultWordRegExp; - const {text, range} = getWordTextAndRange(textEditor, position, wordRegExp); - return trackTiming( - getProviderName(provider) + '.getSuggestionForWord', - () => getSuggestionForWord(textEditor, text, range)); + const { text, range } = (0, (_hyperclickUtils || _load_hyperclickUtils()).getWordTextAndRange)(textEditor, position, wordRegExp); + return (0, (_nuclideAnalytics || _load_nuclideAnalytics()).trackTiming)(getProviderName(provider) + '.getSuggestionForWord', () => getSuggestionForWord(textEditor, text, range)); }; } @@ -144,16 +168,18 @@ export default class Hyperclick { })); } - showSuggestionList(textEditor: TextEditor, suggestion: HyperclickSuggestion): void { + showSuggestionList(textEditor, suggestion) { this._suggestionList.show(textEditor, suggestion); } } -/** Returns the provider name or a default value */ -function getProviderName(provider: HyperclickProvider): string { +exports.default = Hyperclick; /** Returns the provider name or a default value */ + +function getProviderName(provider) { if (provider.providerName != null) { return provider.providerName; } else { return 'unnamed-hyperclick-provider'; } } +module.exports = exports['default']; \ No newline at end of file diff --git a/pkg/hyperclick/lib/HyperclickForTextEditor.js b/pkg/hyperclick/lib/HyperclickForTextEditor.js index d19944c42d..cca8a44bb7 100644 --- a/pkg/hyperclick/lib/HyperclickForTextEditor.js +++ b/pkg/hyperclick/lib/HyperclickForTextEditor.js @@ -1,3 +1,39 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _asyncToGenerator = _interopRequireDefault(require('async-to-generator')); + +var _atom = require('atom'); + +var _hyperclickUtils; + +function _load_hyperclickUtils() { + return _hyperclickUtils = require('./hyperclick-utils'); +} + +var _nuclideAnalytics; + +function _load_nuclideAnalytics() { + return _nuclideAnalytics = require('../../nuclide-analytics'); +} + +var _nuclideLogging; + +function _load_nuclideLogging() { + return _nuclideLogging = require('../../nuclide-logging'); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const logger = (0, (_nuclideLogging || _load_nuclideLogging()).getLogger)(); + +/** + * Construct this object to enable Hyperclick in a text editor. + * Call `dispose` to disable the feature. + */ /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,47 +41,12 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * */ -import type {HyperclickSuggestion} from './types'; -import type Hyperclick from './Hyperclick'; -import type {TimingTracker} from '../../nuclide-analytics'; - -import {CompositeDisposable, Disposable, Point} from 'atom'; -import {getWordTextAndRange} from './hyperclick-utils'; -import invariant from 'assert'; +class HyperclickForTextEditor { -import {trackTiming, startTracking} from '../../nuclide-analytics'; -import {getLogger} from '../../nuclide-logging'; - -const logger = getLogger(); - -/** - * Construct this object to enable Hyperclick in a text editor. - * Call `dispose` to disable the feature. - */ -export default class HyperclickForTextEditor { - _textEditor: atom$TextEditor; - _textEditorView: atom$TextEditorElement; - _hyperclick: Hyperclick; - _lastMouseEvent: ?MouseEvent; - _lastPosition: ?atom$Point; - _lastSuggestionAtMousePromise: ?Promise; - _lastSuggestionAtMouse: ?HyperclickSuggestion; - _navigationMarkers: ?Array; - _lastWordRange: ?atom$Range; - _onMouseMove: (event: Event) => void; - _onMouseDown: (event: Event) => void; - _onKeyDown: (event: Event) => void; - _onKeyUp: (event: Event) => void; - _subscriptions: atom$CompositeDisposable; - _isDestroyed: boolean; - _isLoading: boolean; - _loadingTracker: ?TimingTracker; - _triggerKeys: Set<'shiftKey' | 'ctrlKey' | 'altKey' | 'metaKey'>; - - constructor(textEditor: atom$TextEditor, hyperclick: Hyperclick) { + constructor(textEditor, hyperclick) { this._textEditor = textEditor; this._textEditorView = atom.views.getView(textEditor); @@ -61,7 +62,7 @@ export default class HyperclickForTextEditor { this._navigationMarkers = null; this._lastWordRange = null; - this._subscriptions = new CompositeDisposable(); + this._subscriptions = new _atom.CompositeDisposable(); this._onMouseMove = this._onMouseMove.bind(this); this._onMouseDown = this._onMouseDown.bind(this); @@ -71,34 +72,31 @@ export default class HyperclickForTextEditor { this._textEditorView.addEventListener('keydown', this._onKeyDown); this._onKeyUp = this._onKeyUp.bind(this); this._textEditorView.addEventListener('keyup', this._onKeyUp); - (this: any)._onContextMenu = this._onContextMenu.bind(this); + this._onContextMenu = this._onContextMenu.bind(this); this._textEditorView.addEventListener('contextmenu', this._onContextMenu); this._subscriptions.add(atom.commands.add(this._textEditorView, { - 'hyperclick:confirm-cursor': () => this._confirmSuggestionAtCursor(), + 'hyperclick:confirm-cursor': () => this._confirmSuggestionAtCursor() })); this._isDestroyed = false; this._isLoading = false; this._loadingTracker = null; - this._subscriptions.add( - atom.config.observe( - process.platform === 'darwin' ? 'nuclide.hyperclick.darwinTriggerKeys' : - (process.platform === 'win32' ? 'nuclide.hyperclick.win32TriggerKeys' : - 'nuclide.hyperclick.linuxTriggerKeys'), - (newValue: string) => { - // For all Flow knows, newValue.split could return any old strings - this._triggerKeys = (new Set(newValue.split(',')): Set); - }, - ), - ); + this._subscriptions.add(atom.config.observe(process.platform === 'darwin' ? 'nuclide.hyperclick.darwinTriggerKeys' : process.platform === 'win32' ? 'nuclide.hyperclick.win32TriggerKeys' : 'nuclide.hyperclick.linuxTriggerKeys', newValue => { + // For all Flow knows, newValue.split could return any old strings + this._triggerKeys = new Set(newValue.split(',')); + })); } - _setupMouseListeners(): void { - const getLinesDomNode = (): HTMLElement => { - const {component} = this._textEditorView; - invariant(component); + _setupMouseListeners() { + const getLinesDomNode = () => { + const { component } = this._textEditorView; + + if (!component) { + throw new Error('Invariant violation: "component"'); + } + return component.linesComponent.getDomNode(); }; const removeMouseListeners = () => { @@ -112,23 +110,26 @@ export default class HyperclickForTextEditor { getLinesDomNode().addEventListener('mousedown', this._onMouseDown); getLinesDomNode().addEventListener('mousemove', this._onMouseMove); }; - this._subscriptions.add(new Disposable(removeMouseListeners)); + this._subscriptions.add(new _atom.Disposable(removeMouseListeners)); this._subscriptions.add(this._textEditorView.onDidDetach(removeMouseListeners)); this._subscriptions.add(this._textEditorView.onDidAttach(addMouseListeners)); addMouseListeners(); } - _confirmSuggestion(suggestion: HyperclickSuggestion): void { + _confirmSuggestion(suggestion) { if (Array.isArray(suggestion.callback) && suggestion.callback.length > 0) { this._hyperclick.showSuggestionList(this._textEditor, suggestion); } else { - invariant(typeof suggestion.callback === 'function'); + if (!(typeof suggestion.callback === 'function')) { + throw new Error('Invariant violation: "typeof suggestion.callback === \'function\'"'); + } + suggestion.callback(); } } - _onContextMenu(event: Event): void { - const mouseEvent: MouseEvent = (event: any); + _onContextMenu(event) { + const mouseEvent = event; // If the key trigger happens to cause the context menu to show up, then // cancel it. By this point, it's too late to know if you're at a suggestion // position to be more fine grained. So if your trigger keys are "ctrl+cmd", @@ -138,8 +139,8 @@ export default class HyperclickForTextEditor { } } - _onMouseMove(event: Event): void { - const mouseEvent: MouseEvent = (event: any); + _onMouseMove(event) { + const mouseEvent = event; if (this._isLoading) { // Show the loading cursor. this._textEditorView.classList.add('hyperclick-loading'); @@ -148,11 +149,10 @@ export default class HyperclickForTextEditor { // We save the last `MouseEvent` so the user can trigger Hyperclick by // pressing the key without moving the mouse again. We only save the // relevant properties to prevent retaining a reference to the event. - this._lastMouseEvent = ({ + this._lastMouseEvent = { clientX: mouseEvent.clientX, - clientY: mouseEvent.clientY, - }: any); - + clientY: mouseEvent.clientY + }; // Don't fetch suggestions if the mouse is still in the same 'word', where // 'word' is a whitespace-delimited group of characters. @@ -161,12 +161,11 @@ export default class HyperclickForTextEditor { // fetch suggestions because the new word might be between those ranges. // This should be ok because it will reuse that last suggestion until the // mouse moves off of it. - const lastSuggestionIsNotMultiRange = !this._lastSuggestionAtMouse || - !Array.isArray(this._lastSuggestionAtMouse.range); + const lastSuggestionIsNotMultiRange = !this._lastSuggestionAtMouse || !Array.isArray(this._lastSuggestionAtMouse.range); if (this._isMouseAtLastWordRange() && lastSuggestionIsNotMultiRange) { return; } - const {range} = getWordTextAndRange(this._textEditor, this._getMousePositionAsBufferPosition()); + const { range } = (0, (_hyperclickUtils || _load_hyperclickUtils()).getWordTextAndRange)(this._textEditor, this._getMousePositionAsBufferPosition()); this._lastWordRange = range; if (this._isHyperclickEvent(mouseEvent)) { @@ -180,8 +179,8 @@ export default class HyperclickForTextEditor { } } - _onMouseDown(event: Event): void { - const mouseEvent: MouseEvent = (event: any); + _onMouseDown(event) { + const mouseEvent = event; if (!this._isHyperclickEvent(mouseEvent) || !this._isMouseAtLastSuggestion()) { return; } @@ -200,16 +199,16 @@ export default class HyperclickForTextEditor { this._clearSuggestion(); } - _onKeyDown(event: Event): void { - const mouseEvent: MouseEvent = (event: any); + _onKeyDown(event) { + const mouseEvent = event; // Show the suggestion at the last known mouse position. if (this._isHyperclickEvent(mouseEvent)) { this._setSuggestionForLastMouseEvent(); } } - _onKeyUp(event: Event): void { - const mouseEvent: MouseEvent = (event: any); + _onKeyUp(event) { + const mouseEvent = event; if (!this._isHyperclickEvent(mouseEvent)) { this._clearSuggestion(); } @@ -218,66 +217,80 @@ export default class HyperclickForTextEditor { /** * Returns a `Promise` that's resolved when the latest suggestion's available. */ - getSuggestionAtMouse(): Promise { + getSuggestionAtMouse() { return this._lastSuggestionAtMousePromise || Promise.resolve(null); } - async _setSuggestionForLastMouseEvent(): Promise { - if (!this._lastMouseEvent) { - return; - } - - const position = this._getMousePositionAsBufferPosition(); + _setSuggestionForLastMouseEvent() { + var _this = this; - if (this._lastSuggestionAtMouse != null) { - const {range} = this._lastSuggestionAtMouse; - invariant(range, 'Hyperclick result must have a valid Range'); - if (this._isPositionInRange(position, range)) { + return (0, _asyncToGenerator.default)(function* () { + if (!_this._lastMouseEvent) { return; } - } - // this._lastSuggestionAtMouse will only be set if hyperclick returned a promise that - // resolved to a non-null value. So, in order to not ask hyperclick for the same thing - // again and again which will be anyway null, we check if the mouse position has changed. - if (this._lastPosition && position.compare(this._lastPosition) === 0) { - return; - } - this._isLoading = true; - this._loadingTracker = startTracking('hyperclick-loading'); + const position = _this._getMousePositionAsBufferPosition(); - try { - this._lastPosition = position; - this._lastSuggestionAtMousePromise = - this._hyperclick.getSuggestion(this._textEditor, position); - this._lastSuggestionAtMouse = await this._lastSuggestionAtMousePromise; - if (this._isDestroyed) { - return; - } - if (this._lastSuggestionAtMouse && this._isMouseAtLastSuggestion()) { - // Add the hyperclick markers if there's a new suggestion and it's under the mouse. - this._updateNavigationMarkers(this._lastSuggestionAtMouse.range); - } else { - // Remove all the markers if we've finished loading and there's no suggestion. - this._updateNavigationMarkers(null); + if (_this._lastSuggestionAtMouse != null) { + const { range } = _this._lastSuggestionAtMouse; + + if (!range) { + throw new Error('Hyperclick result must have a valid Range'); + } + + if (_this._isPositionInRange(position, range)) { + return; + } } - if (this._loadingTracker != null) { - this._loadingTracker.onSuccess(); + // this._lastSuggestionAtMouse will only be set if hyperclick returned a promise that + // resolved to a non-null value. So, in order to not ask hyperclick for the same thing + // again and again which will be anyway null, we check if the mouse position has changed. + if (_this._lastPosition && position.compare(_this._lastPosition) === 0) { + return; } - } catch (e) { - if (this._loadingTracker != null) { - this._loadingTracker.onError(e); + + _this._isLoading = true; + _this._loadingTracker = (0, (_nuclideAnalytics || _load_nuclideAnalytics()).startTracking)('hyperclick-loading'); + + try { + _this._lastPosition = position; + _this._lastSuggestionAtMousePromise = _this._hyperclick.getSuggestion(_this._textEditor, position); + _this._lastSuggestionAtMouse = yield _this._lastSuggestionAtMousePromise; + if (_this._isDestroyed) { + return; + } + if (_this._lastSuggestionAtMouse && _this._isMouseAtLastSuggestion()) { + // Add the hyperclick markers if there's a new suggestion and it's under the mouse. + _this._updateNavigationMarkers(_this._lastSuggestionAtMouse.range); + } else { + // Remove all the markers if we've finished loading and there's no suggestion. + _this._updateNavigationMarkers(null); + } + if (_this._loadingTracker != null) { + _this._loadingTracker.onSuccess(); + } + } catch (e) { + if (_this._loadingTracker != null) { + _this._loadingTracker.onError(e); + } + logger.error('Error getting Hyperclick suggestion:', e); + } finally { + _this._doneLoading(); } - logger.error('Error getting Hyperclick suggestion:', e); - } finally { - this._doneLoading(); - } + })(); } - _getMousePositionAsBufferPosition(): atom$Point { - const {component} = this._textEditorView; - invariant(component); - invariant(this._lastMouseEvent); + _getMousePositionAsBufferPosition() { + const { component } = this._textEditorView; + + if (!component) { + throw new Error('Invariant violation: "component"'); + } + + if (!this._lastMouseEvent) { + throw new Error('Invariant violation: "this._lastMouseEvent"'); + } + const screenPosition = component.screenPositionForMouseEvent(this._lastMouseEvent); try { return this._textEditor.bufferPositionForScreenPosition(screenPosition); @@ -287,20 +300,24 @@ export default class HyperclickForTextEditor { // it triggers TextEditorElement's `mousemove` with invalid screen position. // This falls back to returning the start of the editor. logger.error('Hyperclick: Error getting buffer position for screen position:', error); - return new Point(0, 0); + return new _atom.Point(0, 0); } } - _isMouseAtLastSuggestion(): boolean { + _isMouseAtLastSuggestion() { if (!this._lastSuggestionAtMouse) { return false; } - const {range} = this._lastSuggestionAtMouse; - invariant(range, 'Hyperclick result must have a valid Range'); + const { range } = this._lastSuggestionAtMouse; + + if (!range) { + throw new Error('Hyperclick result must have a valid Range'); + } + return this._isPositionInRange(this._getMousePositionAsBufferPosition(), range); } - _isMouseAtLastWordRange(): boolean { + _isMouseAtLastWordRange() { const lastWordRange = this._lastWordRange; if (lastWordRange == null) { return false; @@ -308,34 +325,32 @@ export default class HyperclickForTextEditor { return this._isPositionInRange(this._getMousePositionAsBufferPosition(), lastWordRange); } - _isPositionInRange(position: atom$Point, range: atom$Range | Array): boolean { - return (Array.isArray(range) - ? range.some(r => r.containsPoint(position)) - : range.containsPoint(position)); + _isPositionInRange(position, range) { + return Array.isArray(range) ? range.some(r => r.containsPoint(position)) : range.containsPoint(position); } - _clearSuggestion(): void { + _clearSuggestion() { this._doneLoading(); this._lastSuggestionAtMousePromise = null; this._lastSuggestionAtMouse = null; this._updateNavigationMarkers(null); } - _confirmSuggestionAtCursor(): Promise { - return trackTiming('hyperclick:confirm-cursor', async () => { - const suggestion = await this._hyperclick.getSuggestion( - this._textEditor, - this._textEditor.getCursorBufferPosition()); + _confirmSuggestionAtCursor() { + var _this2 = this; + + return (0, (_nuclideAnalytics || _load_nuclideAnalytics()).trackTiming)('hyperclick:confirm-cursor', (0, _asyncToGenerator.default)(function* () { + const suggestion = yield _this2._hyperclick.getSuggestion(_this2._textEditor, _this2._textEditor.getCursorBufferPosition()); if (suggestion) { - this._confirmSuggestion(suggestion); + _this2._confirmSuggestion(suggestion); } - }); + })); } /** * Add markers for the given range(s), or clears them if `ranges` is null. */ - _updateNavigationMarkers(range: ? (atom$Range | Array)): void { + _updateNavigationMarkers(range) { if (this._navigationMarkers) { this._navigationMarkers.forEach(marker => marker.destroy()); this._navigationMarkers = null; @@ -350,11 +365,8 @@ export default class HyperclickForTextEditor { this._textEditorView.classList.add('hyperclick'); const ranges = Array.isArray(range) ? range : [range]; this._navigationMarkers = ranges.map(markerRange => { - const marker = this._textEditor.markBufferRange(markerRange, {invalidate: 'never'}); - this._textEditor.decorateMarker( - marker, - {type: 'highlight', class: 'hyperclick'}, - ); + const marker = this._textEditor.markBufferRange(markerRange, { invalidate: 'never' }); + this._textEditor.decorateMarker(marker, { type: 'highlight', class: 'hyperclick' }); return marker; }); } @@ -362,16 +374,11 @@ export default class HyperclickForTextEditor { /** * Returns whether an event should be handled by hyperclick or not. */ - _isHyperclickEvent(event: SyntheticKeyboardEvent | MouseEvent): boolean { - return ( - event.shiftKey === this._triggerKeys.has('shiftKey') && - event.ctrlKey === this._triggerKeys.has('ctrlKey') && - event.altKey === this._triggerKeys.has('altKey') && - event.metaKey === this._triggerKeys.has('metaKey') - ); + _isHyperclickEvent(event) { + return event.shiftKey === this._triggerKeys.has('shiftKey') && event.ctrlKey === this._triggerKeys.has('ctrlKey') && event.altKey === this._triggerKeys.has('altKey') && event.metaKey === this._triggerKeys.has('metaKey'); } - _doneLoading(): void { + _doneLoading() { this._isLoading = false; this._loadingTracker = null; this._textEditorView.classList.remove('hyperclick-loading'); @@ -386,3 +393,5 @@ export default class HyperclickForTextEditor { this._subscriptions.dispose(); } } +exports.default = HyperclickForTextEditor; +module.exports = exports['default']; \ No newline at end of file diff --git a/pkg/hyperclick/lib/SuggestionList.js b/pkg/hyperclick/lib/SuggestionList.js index b863b7b893..d4b9e73402 100644 --- a/pkg/hyperclick/lib/SuggestionList.js +++ b/pkg/hyperclick/lib/SuggestionList.js @@ -1,3 +1,8 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,20 +10,12 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * */ -import type {HyperclickSuggestion} from './types'; - -import invariant from 'assert'; - -export default class SuggestionList { - _textEditor: atom$TextEditor; - _suggestion: HyperclickSuggestion; - _suggestionMarker: ?atom$Marker; - _overlayDecoration: ?atom$Decoration; +class SuggestionList { - show(textEditor: atom$TextEditor, suggestion: HyperclickSuggestion): void { + show(textEditor, suggestion) { if (!textEditor || !suggestion) { return; } @@ -28,14 +25,18 @@ export default class SuggestionList { this.hide(); - const {range} = suggestion; - invariant(range); - const {start: position} = Array.isArray(range) ? range[0] : range; + const { range } = suggestion; + + if (!range) { + throw new Error('Invariant violation: "range"'); + } + + const { start: position } = Array.isArray(range) ? range[0] : range; this._suggestionMarker = textEditor.markBufferPosition(position); if (this._suggestionMarker) { this._overlayDecoration = textEditor.decorateMarker(this._suggestionMarker, { type: 'overlay', - item: this, + item: this }); } } @@ -52,11 +53,13 @@ export default class SuggestionList { this._overlayDecoration = undefined; } - getTextEditor(): ?TextEditor { + getTextEditor() { return this._textEditor; } - getSuggestion(): ?HyperclickSuggestion { + getSuggestion() { return this._suggestion; } } +exports.default = SuggestionList; +module.exports = exports['default']; \ No newline at end of file diff --git a/pkg/hyperclick/lib/SuggestionListElement.js b/pkg/hyperclick/lib/SuggestionListElement.js index db8c7a67dc..58ddadce64 100644 --- a/pkg/hyperclick/lib/SuggestionListElement.js +++ b/pkg/hyperclick/lib/SuggestionListElement.js @@ -1,39 +1,30 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the license found in the LICENSE file in - * the root directory of this source tree. - * - * @flow - */ +'use strict'; -/* global HTMLElement */ +Object.defineProperty(exports, "__esModule", { + value: true +}); -import type SuggestionListType from './SuggestionList'; +var _atom = require('atom'); -import {CompositeDisposable, Disposable} from 'atom'; -import {React, ReactDOM} from 'react-for-atom'; -import invariant from 'assert'; +var _reactForAtom = require('react-for-atom'); /** * We need to create this custom HTML element so we can hook into the view * registry. The overlay decoration only works through the view registry. */ class SuggestionListElement extends HTMLElement { - _model: SuggestionListType; - initialize(model: SuggestionListType) { + initialize(model) { this._model = model; return this; } - attachedCallback(): mixed { - ReactDOM.render(, this); + attachedCallback() { + _reactForAtom.ReactDOM.render(_reactForAtom.React.createElement(SuggestionList, { suggestionList: this._model }), this); } - detachedCallback(): mixed { - ReactDOM.unmountComponentAtNode(this); + detachedCallback() { + _reactForAtom.ReactDOM.unmountComponentAtNode(this); } dispose() { @@ -41,71 +32,72 @@ class SuggestionListElement extends HTMLElement { this.parentNode.removeChild(this); } } -} - -type Props = { - suggestionList: SuggestionListType, -}; +} /** + * Copyright (c) 2015-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the license found in the LICENSE file in + * the root directory of this source tree. + * + * + */ -type State = { - selectedIndex: number, -}; - -class SuggestionList extends React.Component { - props: Props; - state: State; +/* global HTMLElement */ - _items: Array<{rightLabel?: string, title: string, callback: () => mixed}>; - _textEditor: ?atom$TextEditor; - _subscriptions: atom$CompositeDisposable; - _boundConfirm: () => void; +class SuggestionList extends _reactForAtom.React.Component { - constructor(props: Props) { + constructor(props) { super(props); this.state = { - selectedIndex: 0, + selectedIndex: 0 }; - this._subscriptions = new CompositeDisposable(); + this._subscriptions = new _atom.CompositeDisposable(); this._boundConfirm = this._confirm.bind(this); } componentWillMount() { - const {suggestionList} = this.props; + const { suggestionList } = this.props; const suggestion = suggestionList.getSuggestion(); // TODO(nmote): This is assuming `suggestion.callback` is always an Array, which is not true // according to hyperclick/lib/types. It can also be a function. - invariant(suggestion != null && Array.isArray(suggestion.callback)); + + if (!(suggestion != null && Array.isArray(suggestion.callback))) { + throw new Error('Invariant violation: "suggestion != null && Array.isArray(suggestion.callback)"'); + } + this._items = suggestion.callback; this._textEditor = suggestionList.getTextEditor(); } componentDidMount() { const textEditor = this._textEditor; - invariant(textEditor); + + if (!textEditor) { + throw new Error('Invariant violation: "textEditor"'); + } + const textEditorView = atom.views.getView(textEditor); const boundClose = this._close.bind(this); - this._subscriptions.add( - atom.commands.add(textEditorView, { - 'core:move-up': this._moveSelectionUp.bind(this), - 'core:move-down': this._moveSelectionDown.bind(this), - 'core:move-to-top': this._moveSelectionToTop.bind(this), - 'core:move-to-bottom': this._moveSelectionToBottom.bind(this), - 'core:cancel': boundClose, - 'editor:newline': this._boundConfirm, - })); + this._subscriptions.add(atom.commands.add(textEditorView, { + 'core:move-up': this._moveSelectionUp.bind(this), + 'core:move-down': this._moveSelectionDown.bind(this), + 'core:move-to-top': this._moveSelectionToTop.bind(this), + 'core:move-to-bottom': this._moveSelectionToBottom.bind(this), + 'core:cancel': boundClose, + 'editor:newline': this._boundConfirm + })); this._subscriptions.add(textEditor.onDidChange(boundClose)); this._subscriptions.add(textEditor.onDidChangeCursorPosition(boundClose)); // Prevent scrolling the editor when scrolling the suggestion list. const stopPropagation = event => event.stopPropagation(); - ReactDOM.findDOMNode(this.refs.scroller).addEventListener('mousewheel', stopPropagation); - this._subscriptions.add(new Disposable(() => { - ReactDOM.findDOMNode(this.refs.scroller) - .removeEventListener('mousewheel', stopPropagation); + _reactForAtom.ReactDOM.findDOMNode(this.refs.scroller).addEventListener('mousewheel', stopPropagation); + this._subscriptions.add(new _atom.Disposable(() => { + _reactForAtom.ReactDOM.findDOMNode(this.refs.scroller).removeEventListener('mousewheel', stopPropagation); })); - const keydown = (event: KeyboardEvent) => { + const keydown = event => { // If the user presses the enter key, confirm the selection. if (event.keyCode === 13) { event.stopImmediatePropagation(); @@ -113,7 +105,7 @@ class SuggestionList extends React.Component { } }; textEditorView.addEventListener('keydown', keydown); - this._subscriptions.add(new Disposable(() => { + this._subscriptions.add(new _atom.Disposable(() => { textEditorView.removeEventListener('keydown', keydown); })); } @@ -124,27 +116,33 @@ class SuggestionList extends React.Component { if (index === this.state.selectedIndex) { className += ' selected'; } - return ( -
  • - {item.title} - {item.rightLabel} -
  • + return _reactForAtom.React.createElement( + 'li', + { className: className, + key: index, + onMouseDown: this._boundConfirm, + onMouseEnter: this._setSelectedIndex.bind(this, index) }, + item.title, + _reactForAtom.React.createElement( + 'span', + { className: 'right-label' }, + item.rightLabel + ) ); }); - return ( -
    -
      - {itemComponents} -
    -
    + return _reactForAtom.React.createElement( + 'div', + { className: 'popover-list select-list hyperclick-suggestion-list-scroller', ref: 'scroller' }, + _reactForAtom.React.createElement( + 'ol', + { className: 'list-group', ref: 'selectionList' }, + itemComponents + ) ); } - componentDidUpdate(prevProps: Object, prevState: Object) { + componentDidUpdate(prevProps, prevState) { if (prevState.selectedIndex !== this.state.selectedIndex) { this._updateScrollPosition(); } @@ -163,15 +161,15 @@ class SuggestionList extends React.Component { this.props.suggestionList.hide(); } - _setSelectedIndex(index: number) { + _setSelectedIndex(index) { this.setState({ - selectedIndex: index, + selectedIndex: index }); } _moveSelectionDown(event) { if (this.state.selectedIndex < this._items.length - 1) { - this.setState({selectedIndex: this.state.selectedIndex + 1}); + this.setState({ selectedIndex: this.state.selectedIndex + 1 }); } else { this._moveSelectionToTop(); } @@ -182,7 +180,7 @@ class SuggestionList extends React.Component { _moveSelectionUp(event) { if (this.state.selectedIndex > 0) { - this.setState({selectedIndex: this.state.selectedIndex - 1}); + this.setState({ selectedIndex: this.state.selectedIndex - 1 }); } else { this._moveSelectionToBottom(); } @@ -192,26 +190,27 @@ class SuggestionList extends React.Component { } _moveSelectionToBottom(event) { - this.setState({selectedIndex: Math.max(this._items.length - 1, 0)}); + this.setState({ selectedIndex: Math.max(this._items.length - 1, 0) }); if (event) { event.stopImmediatePropagation(); } } _moveSelectionToTop(event) { - this.setState({selectedIndex: 0}); + this.setState({ selectedIndex: 0 }); if (event) { event.stopImmediatePropagation(); } } _updateScrollPosition() { - const listNode = ReactDOM.findDOMNode(this.refs.selectionList); + const listNode = _reactForAtom.ReactDOM.findDOMNode(this.refs.selectionList); const selectedNode = listNode.getElementsByClassName('selected')[0]; selectedNode.scrollIntoViewIfNeeded(false); } } -export default document.registerElement('hyperclick-suggestion-list', { - prototype: SuggestionListElement.prototype, +exports.default = document.registerElement('hyperclick-suggestion-list', { + prototype: SuggestionListElement.prototype }); +module.exports = exports['default']; \ No newline at end of file diff --git a/pkg/hyperclick/lib/hyperclick-utils.js b/pkg/hyperclick/lib/hyperclick-utils.js index 8f29679d75..fa8e0ad782 100644 --- a/pkg/hyperclick/lib/hyperclick-utils.js +++ b/pkg/hyperclick/lib/hyperclick-utils.js @@ -1,18 +1,14 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the license found in the LICENSE file in - * the root directory of this source tree. - * - * @flow - */ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.defaultWordRegExpForEditor = defaultWordRegExpForEditor; +exports.getWordTextAndRange = getWordTextAndRange; -import {Range} from 'atom'; +var _atom = require('atom'); -export function defaultWordRegExpForEditor( - textEditor: atom$TextEditor, -): ?RegExp { +function defaultWordRegExpForEditor(textEditor) { const lastCursor = textEditor.getLastCursor(); if (!lastCursor) { return null; @@ -24,15 +20,19 @@ export function defaultWordRegExpForEditor( * Returns the text and range for the word that contains the given position. */ -type WordTextAndRange = {text: string, range: Range}; +/** + * Copyright (c) 2015-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the license found in the LICENSE file in + * the root directory of this source tree. + * + * + */ -export function getWordTextAndRange( - textEditor: TextEditor, - position: atom$Point, - wordRegExp_?: ?RegExp, -): WordTextAndRange { +function getWordTextAndRange(textEditor, position, wordRegExp_) { let wordRegExp = wordRegExp_; - let textAndRange: ?WordTextAndRange = null; + let textAndRange = null; wordRegExp = wordRegExp || defaultWordRegExpForEditor(textEditor); @@ -42,7 +42,7 @@ export function getWordTextAndRange( if (data.range.containsPoint(position)) { textAndRange = { text: data.matchText, - range: data.range, + range: data.range }; data.stop(); } else if (data.range.end.column > position.column) { @@ -53,8 +53,8 @@ export function getWordTextAndRange( } if (!textAndRange) { - textAndRange = {text: '', range: new Range(position, position)}; + textAndRange = { text: '', range: new _atom.Range(position, position) }; } return textAndRange; -} +} \ No newline at end of file diff --git a/pkg/hyperclick/lib/main.js b/pkg/hyperclick/lib/main.js index 9d13f0556c..29d7f77d0d 100644 --- a/pkg/hyperclick/lib/main.js +++ b/pkg/hyperclick/lib/main.js @@ -1,50 +1,72 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the license found in the LICENSE file in - * the root directory of this source tree. - * - * @flow - */ +'use strict'; -import type {HyperclickProvider} from './types'; +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.activate = activate; +exports.deactivate = deactivate; +exports.consumeProvider = consumeProvider; +exports.observeTextEditor = observeTextEditor; +exports.provideHyperclickView = provideHyperclickView; -import {Disposable} from 'atom'; -import Hyperclick from './Hyperclick'; -import SuggestionList from './SuggestionList'; -import SuggestionListElement from './SuggestionListElement'; +var _atom = require('atom'); -let hyperclick: ?Hyperclick = null; +var _Hyperclick; + +function _load_Hyperclick() { + return _Hyperclick = _interopRequireDefault(require('./Hyperclick')); +} + +var _SuggestionList; + +function _load_SuggestionList() { + return _SuggestionList = _interopRequireDefault(require('./SuggestionList')); +} -export function activate() { - hyperclick = new Hyperclick(); +var _SuggestionListElement; + +function _load_SuggestionListElement() { + return _SuggestionListElement = _interopRequireDefault(require('./SuggestionListElement')); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +let hyperclick = null; /** + * Copyright (c) 2015-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the license found in the LICENSE file in + * the root directory of this source tree. + * + * + */ + +function activate() { + hyperclick = new (_Hyperclick || _load_Hyperclick()).default(); // FB-only: override the symbols-view "Go To Declaration" context menu item // with the Hyperclick "confirm-cursor" command. // TODO(hansonw): Remove when symbols-view has a proper API. try { // $FlowFB - const {overrideGoToDeclaration} = require('./fb/overrideGoToDeclaration'); + const { overrideGoToDeclaration } = require('./fb/overrideGoToDeclaration'); overrideGoToDeclaration(); } catch (e) { // Ignore. } } -export function deactivate() { +function deactivate() { if (hyperclick != null) { hyperclick.dispose(); hyperclick = null; } } -export function consumeProvider( - provider: HyperclickProvider | Array, -): ?Disposable { +function consumeProvider(provider) { if (hyperclick != null) { hyperclick.consumeProvider(provider); - return new Disposable(() => { + return new _atom.Disposable(() => { if (hyperclick != null) { hyperclick.removeProvider(provider); } @@ -57,17 +79,17 @@ export function consumeProvider( * observed by default by hyperclick. However, if a TextEditor is created via some other means, * (such as a building block for a piece of UI), then it must be observed explicitly. */ -export function observeTextEditor(): (textEditor: atom$TextEditor) => void { - return (textEditor: atom$TextEditor) => { +function observeTextEditor() { + return textEditor => { if (hyperclick != null) { hyperclick.observeTextEditor(textEditor); } }; } -export function provideHyperclickView(model: mixed): ?SuggestionListElement { - if (!(model instanceof SuggestionList)) { +function provideHyperclickView(model) { + if (!(model instanceof (_SuggestionList || _load_SuggestionList()).default)) { return; } - return new SuggestionListElement().initialize(model); -} + return new (_SuggestionListElement || _load_SuggestionListElement()).default().initialize(model); +} \ No newline at end of file diff --git a/pkg/hyperclick/lib/types.js b/pkg/hyperclick/lib/types.js index ef9dd07424..9a390c31f7 100644 --- a/pkg/hyperclick/lib/types.js +++ b/pkg/hyperclick/lib/types.js @@ -1,42 +1 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the license found in the LICENSE file in - * the root directory of this source tree. - * - * @flow - */ - -export type HyperclickProvider = { - // Use this to provide a suggestion for single-word matches. - // Optionally set `wordRegExp` to adjust word-matching. - getSuggestionForWord?: ( - textEditor: atom$TextEditor, - text: string, - range: atom$Range, - ) => Promise, - - wordRegExp?: RegExp, - - // Use this to provide a suggestion if it can have non-contiguous ranges. - // A primary use-case for this is Objective-C methods. - getSuggestion?: ( - textEditor: atom$TextEditor, - position: atom$Point, - ) => Promise, - - // The higher this is, the more precedence the provider gets. Defaults to 0. - priority?: number, - - // Must be unique. Used for analytics. - providerName?: string, -}; - -export type HyperclickSuggestion = { - // The range(s) to underline to provide as a visual cue for clicking. - range: ?atom$Range | ?Array, - - // The function to call when the underlined text is clicked. - callback: (() => mixed) | Array<{rightLabel?: string, title: string, callback: () => mixed}>, -}; +"use strict"; \ No newline at end of file diff --git a/pkg/hyperclick/spec/Hyperclick-spec.js b/pkg/hyperclick/spec/Hyperclick-spec.js deleted file mode 100644 index 869666fdb8..0000000000 --- a/pkg/hyperclick/spec/Hyperclick-spec.js +++ /dev/null @@ -1,864 +0,0 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the license found in the LICENSE file in - * the root directory of this source tree. - * - * @flow - */ - -import type {HyperclickProvider} from '../lib/types'; -import type HyperclickForTextEditor from '../lib/HyperclickForTextEditor'; - -import {Point, Range} from 'atom'; -import {provideHyperclickView} from '../lib/main'; -import Hyperclick from '../lib/Hyperclick'; -import invariant from 'assert'; - -describe('Hyperclick', () => { - let textEditor: atom$TextEditor = (null: any); - let textEditorView: atom$TextEditorElement = (null: any); - let hyperclick: Hyperclick = (null: any); - let hyperclickForTextEditor: HyperclickForTextEditor = (null: any); - - async function setup() { - atom.views.addViewProvider(provideHyperclickView); - - textEditor = await atom.workspace.open('hyperclick.txt'); - textEditorView = atom.views.getView(textEditor); - - // We need the view attached to the DOM for the mouse events to work. - jasmine.attachToDOM(textEditorView); - - hyperclick = new Hyperclick(); - hyperclickForTextEditor = Array.from(hyperclick._hyperclickForTextEditors)[0]; - } - - /** - * Returns the pixel position in the DOM of the text editor's screen position. - * This is used for dispatching mouse events in the text editor. - * - * Adapted from https://github.com/atom/atom/blob/5272584d2910e5b3f2b0f309aab4775eb0f779a6/spec/text-editor-component-spec.coffee#L2845 - */ - function clientCoordinatesForScreenPosition( - screenPosition: atom$Point, - ): {clientX: number, clientY: number} { - const positionOffset = textEditorView.pixelPositionForScreenPosition(screenPosition); - const {component} = textEditorView; - invariant(component != null); - const scrollViewElement = component.domNode.querySelector('.scroll-view'); - invariant(scrollViewElement != null); - const scrollViewClientRect = scrollViewElement.getBoundingClientRect(); - const clientX = scrollViewClientRect.left - + positionOffset.left - - textEditorView.getScrollLeft(); - const clientY = scrollViewClientRect.top - + positionOffset.top - - textEditorView.getScrollTop(); - return {clientX, clientY}; - } - - function dispatch( - eventClass: typeof KeyboardEvent | typeof MouseEvent, - type: string, - position: atom$Point, - properties_?: {clientX?: number, clientY?: number, metaKey?: boolean}, - ): void { - let properties = properties_; - const {clientX, clientY} = clientCoordinatesForScreenPosition(position); - if (properties != null) { - properties.clientX = clientX; - properties.clientY = clientY; - } else { - properties = {clientX, clientY}; - } - const event = new eventClass(type, properties); - let domNode = null; - if (eventClass === MouseEvent) { - const {component} = textEditorView; - invariant(component); - domNode = component.linesComponent.getDomNode(); - } else { - domNode = textEditorView; - } - domNode.dispatchEvent(event); - } - - describe('without line wrapping', () => { - beforeEach(() => { - waitsForPromise(async () => { - await setup(); - }); - }); - - afterEach(() => { - hyperclick.dispose(); - }); - - describe('simple case', () => { - let provider: HyperclickProvider = (null: any); - const position = new Point(0, 1); - - beforeEach(() => { - provider = { - providerName: 'test', - async getSuggestionForWord(sourceTextEditor, text, range) { - return {range, callback: () => {}}; - }, - }; - spyOn(provider, 'getSuggestionForWord').andCallThrough(); - hyperclick.consumeProvider(provider); - }); - it('should call the provider', () => { - waitsForPromise(async () => { - await hyperclick.getSuggestion(textEditor, position); - expect(provider.getSuggestionForWord).toHaveBeenCalled(); - }); - }); - it('should not call a removed provider', () => { - waitsForPromise(async () => { - hyperclick.removeProvider(provider); - await hyperclick.getSuggestion(textEditor, position); - expect(provider.getSuggestionForWord).not.toHaveBeenCalled(); - }); - }); - }); - - describe(' + ', () => { - it('consumes single-word providers without wordRegExp', () => { - waitsForPromise(async () => { - const callback = jasmine.createSpy('callback'); - const provider = { - providerName: 'test', - async getSuggestionForWord(sourceTextEditor, text, range) { - return {range, callback}; - }, - }; - spyOn(provider, 'getSuggestionForWord').andCallThrough(); - hyperclick.consumeProvider(provider); - - const position = new Point(0, 1); - const expectedText = 'word1'; - const expectedRange = Range.fromObject([[0, 0], [0, 5]]); - - dispatch(MouseEvent, 'mousemove', position, {metaKey: true}); - await hyperclickForTextEditor.getSuggestionAtMouse(); - expect(provider.getSuggestionForWord).toHaveBeenCalledWith( - textEditor, - expectedText, - expectedRange); - - dispatch(MouseEvent, 'mousedown', position, {metaKey: true}); - expect(callback.callCount).toBe(1); - }); - }); - - it('consumes single-word providers with wordRegExp', () => { - waitsForPromise(async () => { - const callback = jasmine.createSpy('callback'); - const provider = { - providerName: 'test', - async getSuggestionForWord(sourceTextEditor, text, range) { - return {range, callback}; - }, - wordRegExp: /word/g, - }; - spyOn(provider, 'getSuggestionForWord').andCallThrough(); - hyperclick.consumeProvider(provider); - - const position = new Point(0, 8); - const expectedText = 'word'; - const expectedRange = Range.fromObject([[0, 6], [0, 10]]); - - dispatch(MouseEvent, 'mousemove', position, {metaKey: true}); - await hyperclickForTextEditor.getSuggestionAtMouse(); - expect(provider.getSuggestionForWord).toHaveBeenCalledWith( - textEditor, - expectedText, - expectedRange); - - dispatch(MouseEvent, 'mousedown', position, {metaKey: true}); - expect(callback.callCount).toBe(1); - }); - }); - - it('consumes multi-range providers', () => { - waitsForPromise(async () => { - const callback = jasmine.createSpy('callback'); - const provider = { - providerName: 'test', - async getSuggestion(sourceTextEditor: TextEditor, sourcePosition: Point) { - const range = [ - new Range(sourcePosition, sourcePosition.translate([0, 1])), - new Range(sourcePosition.translate([0, 2]), sourcePosition.translate([0, 3])), - ]; - return {range, callback}; - }, - }; - spyOn(provider, 'getSuggestion').andCallThrough(); - hyperclick.consumeProvider(provider); - - const position = new Point(0, 8); - - dispatch(MouseEvent, 'mousemove', position, {metaKey: true}); - await hyperclickForTextEditor.getSuggestionAtMouse(); - expect(provider.getSuggestion).toHaveBeenCalledWith(textEditor, position); - - dispatch(MouseEvent, 'mousedown', position, {metaKey: true}); - expect(callback.callCount).toBe(1); - }); - }); - - it('consumes multiple providers from different sources', () => { - waitsForPromise(async () => { - const callback1 = jasmine.createSpy('callback'); - const provider1 = { - providerName: 'test', - // Do not return a suggestion, so we can fall through to provider2. - async getSuggestionForWord(sourceTextEditor, text, range) {}, - }; - spyOn(provider1, 'getSuggestionForWord').andCallThrough(); - - const callback2 = jasmine.createSpy('callback'); - const provider2 = { - providerName: 'test', - async getSuggestionForWord(sourceTextEditor, text, range) { - return {range, callback: callback2}; - }, - }; - spyOn(provider2, 'getSuggestionForWord').andCallThrough(); - - hyperclick.consumeProvider(provider1); - hyperclick.consumeProvider(provider2); - - const position = new Point(0, 1); - const expectedText = 'word1'; - const expectedRange = Range.fromObject([[0, 0], [0, 5]]); - - dispatch(MouseEvent, 'mousemove', position, {metaKey: true}); - await hyperclickForTextEditor.getSuggestionAtMouse(); - expect(provider2.getSuggestionForWord).toHaveBeenCalledWith( - textEditor, - expectedText, - expectedRange); - - dispatch(MouseEvent, 'mousedown', position, {metaKey: true}); - expect(callback1.callCount).toBe(0); - expect(callback2.callCount).toBe(1); - }); - }); - - it('consumes multiple providers from the same source', () => { - waitsForPromise(async () => { - const callback1 = jasmine.createSpy('callback'); - const provider1 = { - providerName: 'test', - // Do not return a suggestion, so we can fall through to provider2. - async getSuggestionForWord(sourceTextEditor, text, range) {}, - }; - spyOn(provider1, 'getSuggestionForWord').andCallThrough(); - - const callback2 = jasmine.createSpy('callback'); - const provider2 = { - providerName: 'test', - async getSuggestionForWord(sourceTextEditor, text, range) { - return {range, callback: callback2}; - }, - }; - spyOn(provider2, 'getSuggestionForWord').andCallThrough(); - - hyperclick.consumeProvider([provider1, provider2]); - - const position = new Point(0, 1); - const expectedText = 'word1'; - const expectedRange = Range.fromObject([[0, 0], [0, 5]]); - - dispatch(MouseEvent, 'mousemove', position, {metaKey: true}); - await hyperclickForTextEditor.getSuggestionAtMouse(); - expect(provider2.getSuggestionForWord).toHaveBeenCalledWith( - textEditor, - expectedText, - expectedRange); - - dispatch(MouseEvent, 'mousedown', position, {metaKey: true}); - expect(callback1.callCount).toBe(0); - expect(callback2.callCount).toBe(1); - }); - }); - }); - - describe('avoids excessive calls', () => { - it('ignores in the same word as the last position', () => { - waitsForPromise(async () => { - const provider = { - providerName: 'test', - async getSuggestionForWord(sourceTextEditor, text, range) { - // Never resolve this, so we know that no suggestion is set. - return new Promise(() => {}); - }, - }; - spyOn(provider, 'getSuggestionForWord').andCallThrough(); - hyperclick.consumeProvider(provider); - - const position = new Point(0, 1); - dispatch(MouseEvent, 'mousemove', position, {metaKey: true}); - dispatch(MouseEvent, 'mousemove', position.translate([0, 1]), {metaKey: true}); - dispatch(MouseEvent, 'mousemove', position.translate([0, 2]), {metaKey: true}); - - expect(provider.getSuggestionForWord.callCount).toBe(1); - }); - }); - - it('ignores in the same single-range as the last suggestion', () => { - waitsForPromise(async () => { - const callback = jasmine.createSpy('callback'); - const provider = { - providerName: 'test', - async getSuggestionForWord(sourceTextEditor, text, range) { - return {range, callback}; - }, - }; - spyOn(provider, 'getSuggestionForWord').andCallThrough(); - hyperclick.consumeProvider(provider); - - const position = new Point(0, 1); - const expectedText = 'word1'; - const expectedRange = Range.fromObject([[0, 0], [0, 5]]); - - dispatch(MouseEvent, 'mousemove', position, {metaKey: true}); - await hyperclickForTextEditor.getSuggestionAtMouse(); - expect(provider.getSuggestionForWord).toHaveBeenCalledWith( - textEditor, - expectedText, - expectedRange); - - dispatch(MouseEvent, 'mousemove', position.translate([0, 1]), {metaKey: true}); - await hyperclickForTextEditor.getSuggestionAtMouse(); - - expect(provider.getSuggestionForWord.callCount).toBe(1); - - dispatch(MouseEvent, 'mousedown', position, {metaKey: true}); - expect(callback.callCount).toBe(1); - }); - }); - - it('handles in a different single-range as the last suggestion', () => { - waitsForPromise(async () => { - const callback = jasmine.createSpy('callback'); - const provider = { - providerName: 'test', - async getSuggestionForWord(sourceTextEditor, text, range) { - return {range, callback}; - }, - }; - spyOn(provider, 'getSuggestionForWord').andCallThrough(); - hyperclick.consumeProvider(provider); - - const position1 = new Point(0, 1); - const expectedText1 = 'word1'; - const expectedRange1 = Range.fromObject([[0, 0], [0, 5]]); - - dispatch(MouseEvent, 'mousemove', position1, {metaKey: true}); - await hyperclickForTextEditor.getSuggestionAtMouse(); - expect(provider.getSuggestionForWord).toHaveBeenCalledWith( - textEditor, - expectedText1, - expectedRange1); - - const position2 = new Point(0, 8); - const expectedText2 = 'word2'; - const expectedRange2 = Range.fromObject([[0, 6], [0, 11]]); - dispatch(MouseEvent, 'mousemove', position2, {metaKey: true}); - await hyperclickForTextEditor.getSuggestionAtMouse(); - expect(provider.getSuggestionForWord).toHaveBeenCalledWith( - textEditor, - expectedText2, - expectedRange2); - - expect(provider.getSuggestionForWord.callCount).toBe(2); - - dispatch(MouseEvent, 'mousedown', position2, {metaKey: true}); - expect(callback.callCount).toBe(1); - }); - }); - - it('ignores in the same multi-range as the last suggestion', () => { - waitsForPromise(async () => { - const range = [ - new Range(new Point(0, 1), new Point(0, 2)), - new Range(new Point(0, 4), new Point(0, 5)), - ]; - const callback = jasmine.createSpy('callback'); - const provider = { - providerName: 'test', - async getSuggestion(sourceTextEditor, sourcePosition) { - return {range, callback}; - }, - }; - spyOn(provider, 'getSuggestion').andCallThrough(); - hyperclick.consumeProvider(provider); - - const position = new Point(0, 1); - - dispatch(MouseEvent, 'mousemove', position, {metaKey: true}); - await hyperclickForTextEditor.getSuggestionAtMouse(); - expect(provider.getSuggestion).toHaveBeenCalledWith(textEditor, position); - - dispatch(MouseEvent, 'mousemove', new Point(0, 4), {metaKey: true}); - await hyperclickForTextEditor.getSuggestionAtMouse(); - - expect(provider.getSuggestion.callCount).toBe(1); - - dispatch(MouseEvent, 'mousedown', position, {metaKey: true}); - expect(callback.callCount).toBe(1); - }); - }); - - it('ignores when out of result range', () => { - waitsForPromise(async () => { - const callback = jasmine.createSpy('callback'); - const provider = { - providerName: 'test', - async getSuggestionForWord(sourceTextEditor, text, range) { - return {range, callback}; - }, - }; - spyOn(provider, 'getSuggestionForWord').andCallThrough(); - hyperclick.consumeProvider(provider); - - const inRangePosition = new Point(0, 1); - const outOfRangePosition = new Point(1, 0); - const expectedText = 'word1'; - const expectedRange = Range.fromObject([[0, 0], [0, 5]]); - - dispatch(MouseEvent, 'mousemove', inRangePosition, {metaKey: true}); - await hyperclickForTextEditor.getSuggestionAtMouse(); - expect(provider.getSuggestionForWord).toHaveBeenCalledWith( - textEditor, - expectedText, - expectedRange); - - dispatch(MouseEvent, 'mousemove', outOfRangePosition, {metaKey: true}); - dispatch(MouseEvent, 'mousedown', outOfRangePosition, {metaKey: true}); - expect(callback.callCount).toBe(0); - }); - }); - }); - - describe('adds the `hyperclick` CSS class', () => { - const provider = { - providerName: 'test', - async getSuggestionForWord(sourceTextEditor, text, range) { - return {range, callback() {}}; - }, - }; - - beforeEach(() => { - hyperclick.consumeProvider(provider); - }); - - it('adds on , removes on ', () => { - waitsForPromise(async () => { - const position = new Point(0, 1); - - expect(textEditorView.classList.contains('hyperclick')).toBe(false); - - dispatch(MouseEvent, 'mousemove', position, {metaKey: true}); - await hyperclickForTextEditor.getSuggestionAtMouse(); - expect(textEditorView.classList.contains('hyperclick')).toBe(true); - - dispatch(MouseEvent, 'mousedown', position, {metaKey: true}); - expect(textEditorView.classList.contains('hyperclick')).toBe(false); - }); - }); - - it('adds on , removes on ', () => { - waitsForPromise(async () => { - const position = new Point(0, 1); - - // We need to move the mouse once, so Hyperclick knows where it is. - dispatch(MouseEvent, 'mousemove', position); - expect(textEditorView.classList.contains('hyperclick')).toBe(false); - - dispatch(KeyboardEvent, 'keydown', position, {metaKey: true}); - await hyperclickForTextEditor.getSuggestionAtMouse(); - expect(textEditorView.classList.contains('hyperclick')).toBe(true); - - dispatch(KeyboardEvent, 'keyup', position); - expect(textEditorView.classList.contains('hyperclick')).toBe(false); - }); - }); - }); - - describe('hyperclick:confirm-cursor', () => { - it('confirms the suggestion at the cursor even if the mouse moved', () => { - waitsForPromise(async () => { - const callback = jasmine.createSpy('callback'); - const provider = { - providerName: 'test', - async getSuggestionForWord(sourceTextEditor, text, range) { - return {range, callback}; - }, - }; - spyOn(provider, 'getSuggestionForWord').andCallThrough(); - hyperclick.consumeProvider(provider); - - const mousePosition = new Point(0, 1); - dispatch(MouseEvent, 'mousemove', mousePosition, {metaKey: true}); - await hyperclickForTextEditor.getSuggestionAtMouse(); - - textEditor.setCursorBufferPosition(new Point(0, 8)); - atom.commands.dispatch(textEditorView, 'hyperclick:confirm-cursor'); - expect(provider.getSuggestionForWord).toHaveBeenCalledWith( - textEditor, - 'word2', - Range.fromObject([[0, 6], [0, 11]])); - waitsFor(() => callback.callCount === 1); - }); - }); - }); - - describe('priority', () => { - it('confirms higher priority provider when it is consumed first', () => { - waitsForPromise(async () => { - const callback1 = jasmine.createSpy('callback'); - const provider1 = { - providerName: 'test', - async getSuggestionForWord(sourceTextEditor, text, range) { - return {range, callback: callback1}; - }, - priority: 5, - }; - hyperclick.consumeProvider(provider1); - - const callback2 = jasmine.createSpy('callback'); - const provider2 = { - providerName: 'test', - async getSuggestionForWord(sourceTextEditor, text, range) { - return {range, callback: callback1}; - }, - priority: 3, - }; - hyperclick.consumeProvider(provider2); - - const mousePosition = new Point(0, 1); - dispatch(MouseEvent, 'mousemove', mousePosition, {metaKey: true}); - await hyperclickForTextEditor.getSuggestionAtMouse(); - dispatch(MouseEvent, 'mousedown', mousePosition, {metaKey: true}); - - expect(callback1.callCount).toBe(1); - expect(callback2.callCount).toBe(0); - }); - }); - - it('confirms higher priority provider when it is consumed last', () => { - waitsForPromise(async () => { - const callback1 = jasmine.createSpy('callback'); - const provider1 = { - providerName: 'test', - async getSuggestionForWord(sourceTextEditor, text, range) { - return {range, callback: callback1}; - }, - priority: 3, - }; - hyperclick.consumeProvider(provider1); - - const callback2 = jasmine.createSpy('callback'); - const provider2 = { - providerName: 'test', - async getSuggestionForWord(sourceTextEditor, text, range) { - return {range, callback: callback2}; - }, - priority: 5, - }; - hyperclick.consumeProvider(provider2); - - const mousePosition = new Point(0, 1); - dispatch(MouseEvent, 'mousemove', mousePosition, {metaKey: true}); - await hyperclickForTextEditor.getSuggestionAtMouse(); - dispatch(MouseEvent, 'mousedown', mousePosition, {metaKey: true}); - - expect(callback1.callCount).toBe(0); - expect(callback2.callCount).toBe(1); - }); - }); - - it('confirms >0 priority before default priority', () => { - waitsForPromise(async () => { - const callback1 = jasmine.createSpy('callback'); - const provider1 = { - providerName: 'test', - async getSuggestionForWord(sourceTextEditor, text, range) { - return {range, callback: callback1}; - }, - }; - hyperclick.consumeProvider(provider1); - - const callback2 = jasmine.createSpy('callback'); - const provider2 = { - providerName: 'test', - async getSuggestionForWord(sourceTextEditor, text, range) { - return {range, callback: callback2}; - }, - priority: 1, - }; - hyperclick.consumeProvider(provider2); - - const mousePosition = new Point(0, 1); - dispatch(MouseEvent, 'mousemove', mousePosition, {metaKey: true}); - await hyperclickForTextEditor.getSuggestionAtMouse(); - dispatch(MouseEvent, 'mousedown', mousePosition, {metaKey: true}); - - expect(callback1.callCount).toBe(0); - expect(callback2.callCount).toBe(1); - }); - }); - - it('confirms <0 priority after default priority', () => { - waitsForPromise(async () => { - const callback1 = jasmine.createSpy('callback'); - const provider1 = { - providerName: 'test', - async getSuggestionForWord(sourceTextEditor, text, range) { - return {range, callback: callback1}; - }, - priority: -1, - }; - hyperclick.consumeProvider(provider1); - - const callback2 = jasmine.createSpy('callback'); - const provider2 = { - providerName: 'test', - async getSuggestionForWord(sourceTextEditor, text, range) { - return {range, callback: callback2}; - }, - }; - hyperclick.consumeProvider(provider2); - - const mousePosition = new Point(0, 1); - dispatch(MouseEvent, 'mousemove', mousePosition, {metaKey: true}); - await hyperclickForTextEditor.getSuggestionAtMouse(); - dispatch(MouseEvent, 'mousedown', mousePosition, {metaKey: true}); - - expect(callback1.callCount).toBe(0); - expect(callback2.callCount).toBe(1); - }); - }); - - it('confirms same-priority in the order they are consumed', () => { - waitsForPromise(async () => { - const callback1 = jasmine.createSpy('callback'); - const provider1 = { - providerName: 'test', - async getSuggestionForWord(sourceTextEditor, text, range) { - return {range, callback: callback1}; - }, - }; - hyperclick.consumeProvider(provider1); - - const callback2 = jasmine.createSpy('callback'); - const provider2 = { - providerName: 'test', - async getSuggestionForWord(sourceTextEditor, text, range) { - return {range, callback: callback2}; - }, - }; - hyperclick.consumeProvider(provider2); - - const mousePosition = new Point(0, 1); - dispatch(MouseEvent, 'mousemove', mousePosition, {metaKey: true}); - await hyperclickForTextEditor.getSuggestionAtMouse(); - dispatch(MouseEvent, 'mousedown', mousePosition, {metaKey: true}); - - expect(callback1.callCount).toBe(1); - expect(callback2.callCount).toBe(0); - }); - }); - - it('confirms highest priority provider when multiple are consumed at a time', () => { - waitsForPromise(async () => { - const callback1 = jasmine.createSpy('callback'); - const provider1 = { - providerName: 'test', - async getSuggestionForWord(sourceTextEditor, text, range) { - return {range, callback: callback1}; - }, - priority: 1, - }; - const callback2 = jasmine.createSpy('callback'); - const provider2 = { - providerName: 'test', - async getSuggestionForWord(sourceTextEditor, text, range) { - return {range, callback: callback2}; - }, - priority: 2, - }; - - hyperclick.consumeProvider([provider1, provider2]); - - const mousePosition = new Point(0, 1); - dispatch(MouseEvent, 'mousemove', mousePosition, {metaKey: true}); - await hyperclickForTextEditor.getSuggestionAtMouse(); - dispatch(MouseEvent, 'mousedown', mousePosition, {metaKey: true}); - - expect(callback1.callCount).toBe(0); - expect(callback2.callCount).toBe(1); - }); - }); - }); - - describe('multiple suggestions', () => { - it('confirms the first suggestion', () => { - waitsForPromise(async () => { - const callback = [ - { - title: 'callback1', - callback: jasmine.createSpy('callback1'), - }, - { - title: 'callback2', - callback: jasmine.createSpy('callback1'), - }, - ]; - const provider = { - providerName: 'test', - async getSuggestionForWord(sourceTextEditor, text, range) { - return {range, callback}; - }, - }; - hyperclick.consumeProvider(provider); - - const position = new Point(0, 1); - dispatch(MouseEvent, 'mousemove', position, {metaKey: true}); - await hyperclickForTextEditor.getSuggestionAtMouse(); - dispatch(MouseEvent, 'mousedown', position, {metaKey: true}); - - const suggestionListEl = textEditorView.querySelector('hyperclick-suggestion-list'); - expect(suggestionListEl).toExist(); - - atom.commands.dispatch(textEditorView, 'editor:newline'); - - expect(callback[0].callback.callCount).toBe(1); - expect(callback[1].callback.callCount).toBe(0); - expect(textEditorView.querySelector('hyperclick-suggestion-list')).not.toExist(); - }); - }); - - it('confirms the second suggestion', () => { - waitsForPromise(async () => { - const callback = [ - { - title: 'callback1', - callback: jasmine.createSpy('callback1'), - }, - { - title: 'callback2', - callback: jasmine.createSpy('callback1'), - }, - ]; - const provider = { - providerName: 'test', - async getSuggestionForWord(sourceTextEditor, text, range) { - return {range, callback}; - }, - }; - hyperclick.consumeProvider(provider); - - const position = new Point(0, 1); - dispatch(MouseEvent, 'mousemove', position, {metaKey: true}); - await hyperclickForTextEditor.getSuggestionAtMouse(); - dispatch(MouseEvent, 'mousedown', position, {metaKey: true}); - - const suggestionListEl = textEditorView.querySelector('hyperclick-suggestion-list'); - expect(suggestionListEl).toExist(); - - atom.commands.dispatch(textEditorView, 'core:move-down'); - atom.commands.dispatch(textEditorView, 'editor:newline'); - - expect(callback[0].callback.callCount).toBe(0); - expect(callback[1].callback.callCount).toBe(1); - expect(textEditorView.querySelector('hyperclick-suggestion-list')).not.toExist(); - }); - }); - - it('is cancelable', () => { - waitsForPromise(async () => { - const callback = [ - { - title: 'callback1', - callback: jasmine.createSpy('callback1'), - }, - { - title: 'callback2', - callback: jasmine.createSpy('callback1'), - }, - ]; - const provider = { - providerName: 'test', - async getSuggestionForWord(sourceTextEditor, text, range) { - return {range, callback}; - }, - }; - hyperclick.consumeProvider(provider); - - const position = new Point(0, 1); - dispatch(MouseEvent, 'mousemove', position, {metaKey: true}); - await hyperclickForTextEditor.getSuggestionAtMouse(); - dispatch(MouseEvent, 'mousedown', position, {metaKey: true}); - - const suggestionListEl = textEditorView.querySelector('hyperclick-suggestion-list'); - expect(suggestionListEl).toExist(); - - atom.commands.dispatch(textEditorView, 'core:cancel'); - - expect(callback[0].callback.callCount).toBe(0); - expect(callback[1].callback.callCount).toBe(0); - expect(textEditorView.querySelector('hyperclick-suggestion-list')).not.toExist(); - }); - }); - }); - }); - - describe('with line wrapping', () => { - beforeEach(() => { - waitsForPromise(async () => { - atom.config.set('editor.softWrap', true); - atom.config.set('editor.softWrapAtPreferredLineLength', true); - atom.config.set('editor.preferredLineLength', 6); // This wraps each word onto its own line. - await setup(); - }); - }); - - afterEach(() => { - hyperclick.dispose(); - }); - - describe('when the editor has soft-wrapped lines', () => { - it('Hyperclick correctly detects the word being moused over.', () => { - waitsForPromise(async () => { - const callback = jasmine.createSpy('callback'); - const provider = { - providerName: 'test', - async getSuggestionForWord(sourceTextEditor, text, range) { - return {range, callback}; - }, - }; - spyOn(provider, 'getSuggestionForWord').andCallThrough(); - hyperclick.consumeProvider(provider); - - const position = new Point(8, 0); - const expectedText = 'word9'; - const expectedBufferRange = Range.fromObject([[2, 12], [2, 17]]); - dispatch(MouseEvent, 'mousemove', position, {metaKey: true}); - await hyperclickForTextEditor.getSuggestionAtMouse(); - expect(provider.getSuggestionForWord).toHaveBeenCalledWith( - textEditor, - expectedText, - expectedBufferRange); - expect(provider.getSuggestionForWord.callCount).toBe(1); - }); - }); - }); - }); -}); diff --git a/pkg/hyperclick/spec/fixtures/hyperclick.txt b/pkg/hyperclick/spec/fixtures/hyperclick.txt deleted file mode 100644 index 2665b4c392..0000000000 --- a/pkg/hyperclick/spec/fixtures/hyperclick.txt +++ /dev/null @@ -1,3 +0,0 @@ -word1 word2 word3 -word4 word5 word6 -word7 word8 word9 diff --git a/pkg/nuclide-adb-logcat/lib/Activation.js b/pkg/nuclide-adb-logcat/lib/Activation.js index 7e6d2ca393..2023cb2922 100644 --- a/pkg/nuclide-adb-logcat/lib/Activation.js +++ b/pkg/nuclide-adb-logcat/lib/Activation.js @@ -1,88 +1,94 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the license found in the LICENSE file in - * the root directory of this source tree. - * - * @flow - */ +'use strict'; -import type {OutputService} from '../../nuclide-console/lib/types'; +Object.defineProperty(exports, "__esModule", { + value: true +}); -import formatEnoentNotification from '../../commons-atom/format-enoent-notification'; -import {createProcessStream} from './createProcessStream'; -import createMessageStream from './createMessageStream'; -// eslint-disable-next-line nuclide-internal/no-cross-atom-imports -import {LogTailer} from '../../nuclide-console/lib/LogTailer'; -import {CompositeDisposable, Disposable} from 'atom'; -import {Observable} from 'rxjs'; - -export default class Activation { - _disposables: CompositeDisposable; - _logTailer: LogTailer; - - constructor(state: ?Object) { - const message$ = Observable.defer(() => - createMessageStream( - createProcessStream() - // Retry 3 times (unless we get a ENOENT) - .retryWhen(errors => ( - errors.scan( - (errCount, err) => { - if (isNoEntError(err) || errCount >= 2) { - throw err; - } - return errCount + 1; - }, - 0, - ) - )), - ), - ); - - this._logTailer = new LogTailer({ +var _formatEnoentNotification; + +function _load_formatEnoentNotification() { + return _formatEnoentNotification = _interopRequireDefault(require('../../commons-atom/format-enoent-notification')); +} + +var _createProcessStream; + +function _load_createProcessStream() { + return _createProcessStream = require('./createProcessStream'); +} + +var _createMessageStream; + +function _load_createMessageStream() { + return _createMessageStream = _interopRequireDefault(require('./createMessageStream')); +} + +var _LogTailer; + +function _load_LogTailer() { + return _LogTailer = require('../../nuclide-console/lib/LogTailer'); +} + +var _atom = require('atom'); + +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js'); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +class Activation { + + constructor(state) { + const message$ = _rxjsBundlesRxMinJs.Observable.defer(() => (0, (_createMessageStream || _load_createMessageStream()).default)((0, (_createProcessStream || _load_createProcessStream()).createProcessStream)() + // Retry 3 times (unless we get a ENOENT) + .retryWhen(errors => errors.scan((errCount, err) => { + if (isNoEntError(err) || errCount >= 2) { + throw err; + } + return errCount + 1; + }, 0)))); + + this._logTailer = new (_LogTailer || _load_LogTailer()).LogTailer({ name: 'adb Logcat', messages: message$, trackingEvents: { start: 'adb-logcat:start', stop: 'adb-logcat:stop', - restart: 'adb-logcat:restart', + restart: 'adb-logcat:restart' }, handleError(err) { if (isNoEntError(err)) { - const {message, meta} = formatEnoentNotification({ + const { message, meta } = (0, (_formatEnoentNotification || _load_formatEnoentNotification()).default)({ feature: 'Tailing Android (adb) logs', toolName: 'adb', - pathSetting: 'nuclide-adb-logcat.pathToAdb', + pathSetting: 'nuclide-adb-logcat.pathToAdb' }); atom.notifications.addError(message, meta); return; } throw err; - }, + } }); - this._disposables = new CompositeDisposable( - new Disposable(() => { this._logTailer.stop(); }), - atom.commands.add('atom-workspace', { - 'nuclide-adb-logcat:start': () => this._logTailer.start(), - 'nuclide-adb-logcat:stop': () => this._logTailer.stop(), - 'nuclide-adb-logcat:restart': () => this._logTailer.restart(), - }), - ); + this._disposables = new _atom.CompositeDisposable(new _atom.Disposable(() => { + this._logTailer.stop(); + }), atom.commands.add('atom-workspace', { + 'nuclide-adb-logcat:start': () => this._logTailer.start(), + 'nuclide-adb-logcat:stop': () => this._logTailer.stop(), + 'nuclide-adb-logcat:restart': () => this._logTailer.restart() + })); } - consumeOutputService(api: OutputService): void { - this._disposables.add( - api.registerOutputProvider({ - id: 'adb logcat', - messages: this._logTailer.getMessages(), - observeStatus: cb => this._logTailer.observeStatus(cb), - start: () => { this._logTailer.start(); }, - stop: () => { this._logTailer.stop(); }, - }), - ); + consumeOutputService(api) { + this._disposables.add(api.registerOutputProvider({ + id: 'adb logcat', + messages: this._logTailer.getMessages(), + observeStatus: cb => this._logTailer.observeStatus(cb), + start: () => { + this._logTailer.start(); + }, + stop: () => { + this._logTailer.stop(); + } + })); } dispose() { @@ -90,4 +96,17 @@ export default class Activation { } } -const isNoEntError = err => (err: any).code === 'ENOENT'; +exports.default = Activation; +// eslint-disable-next-line nuclide-internal/no-cross-atom-imports +/** + * Copyright (c) 2015-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the license found in the LICENSE file in + * the root directory of this source tree. + * + * + */ + +const isNoEntError = err => err.code === 'ENOENT'; +module.exports = exports['default']; \ No newline at end of file diff --git a/pkg/nuclide-adb-logcat/lib/createMessage.js b/pkg/nuclide-adb-logcat/lib/createMessage.js index 4fe5eb121c..ea35fb52c8 100644 --- a/pkg/nuclide-adb-logcat/lib/createMessage.js +++ b/pkg/nuclide-adb-logcat/lib/createMessage.js @@ -1,3 +1,14 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = createMessage; + + +/** + * Convert a structured logcat entry into the format that nuclide-console wants. + */ /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,37 +16,36 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * */ -import type {Level, Message} from '../../nuclide-console/lib/types'; -import type {LogcatEntry, Priority} from './types'; - -/** - * Convert a structured logcat entry into the format that nuclide-console wants. - */ -export default function createMessage(entry: LogcatEntry): Message { +function createMessage(entry) { const priority = entry.metadata && entry.metadata.priority || 'I'; const tag = entry.metadata && entry.metadata.tag || null; return { text: entry.message, level: priorityToLevel(priority), - tags: tag ? [tag] : null, + tags: tag ? [tag] : null }; } -function priorityToLevel(priority: Priority): Level { +function priorityToLevel(priority) { switch (priority) { - case 'W': // warn + case 'W': + // warn return 'warning'; case 'E': // error - case 'F': // fatal + case 'F': + // fatal return 'error'; - case 'S': // silent + case 'S': + // silent throw new Error('Silent messages should be filtered'); - case 'D': // debug + case 'D': + // debug return 'debug'; - case 'I': // info + case 'I': + // info // Even though the console has an "info" level, this is the default for adb, so we use "log." return 'log'; case 'V': // verbose @@ -43,3 +53,4 @@ function priorityToLevel(priority: Priority): Level { return 'info'; } } +module.exports = exports['default']; \ No newline at end of file diff --git a/pkg/nuclide-adb-logcat/lib/createMessageStream.js b/pkg/nuclide-adb-logcat/lib/createMessageStream.js index 97a2b91d93..7c43084cec 100644 --- a/pkg/nuclide-adb-logcat/lib/createMessageStream.js +++ b/pkg/nuclide-adb-logcat/lib/createMessageStream.js @@ -1,3 +1,38 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = createMessageStream; + +var _featureConfig; + +function _load_featureConfig() { + return _featureConfig = _interopRequireDefault(require('../../commons-atom/featureConfig')); +} + +var _UniversalDisposable; + +function _load_UniversalDisposable() { + return _UniversalDisposable = _interopRequireDefault(require('../../commons-node/UniversalDisposable')); +} + +var _createMessage; + +function _load_createMessage() { + return _createMessage = _interopRequireDefault(require('./createMessage')); +} + +var _parseLogcatMetadata; + +function _load_parseLogcatMetadata() { + return _parseLogcatMetadata = _interopRequireDefault(require('./parseLogcatMetadata')); +} + +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js'); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,22 +40,12 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * */ -import type {Message} from '../../nuclide-console/lib/types'; - -import featureConfig from '../../commons-atom/featureConfig'; -import UniversalDisposable from '../../commons-node/UniversalDisposable'; -import createMessage from './createMessage'; -import parseLogcatMetadata from './parseLogcatMetadata'; -import {Observable} from 'rxjs'; - -export default function createMessageStream( - line$: Observable, -): Observable { +function createMessageStream(line$) { // Separate the lines into groups, beginning with metadata lines. - const messages = Observable.create(observer => { + const messages = _rxjsBundlesRxMinJs.Observable.create(observer => { let buffer = []; let prevMetadata = null; const prevLineIsBlank = () => buffer[buffer.length - 1] === ''; @@ -37,7 +62,7 @@ export default function createMessageStream( observer.next({ metadata: prevMetadata, - message: buffer.join('\n'), + message: buffer.join('\n') }); buffer = []; prevMetadata = null; @@ -45,72 +70,63 @@ export default function createMessageStream( const sharedLine$ = line$.share(); - return new UniversalDisposable( - // Buffer incoming lines. - sharedLine$.subscribe( - // onNext - line => { - let metadata; - const hasPreviousLines = buffer.length > 0; - - if (!hasPreviousLines || prevLineIsBlank()) { - metadata = parseLogcatMetadata(line); - } - - if (metadata) { - // We've reached a new message so the other one must be done. - flush(); - prevMetadata = metadata; - } else { - buffer.push(line); - } - }, - - // onError - error => { - flush(); - observer.error(error); - }, - - // onCompleted - () => { - flush(); - observer.complete(); - }, - ), - - // We know *for certain* that we have a complete entry once we see the metadata for the next - // one. But what if the next one takes a long time to happen? After a certain point, we need - // to just assume we have the complete entry and move on. - sharedLine$.debounceTime(200).subscribe(flush), - ); - }) - .map(createMessage); + return new (_UniversalDisposable || _load_UniversalDisposable()).default( + // Buffer incoming lines. + sharedLine$.subscribe( + // onNext + line => { + let metadata; + const hasPreviousLines = buffer.length > 0; + + if (!hasPreviousLines || prevLineIsBlank()) { + metadata = (0, (_parseLogcatMetadata || _load_parseLogcatMetadata()).default)(line); + } + + if (metadata) { + // We've reached a new message so the other one must be done. + flush(); + prevMetadata = metadata; + } else { + buffer.push(line); + } + }, + + // onError + error => { + flush(); + observer.error(error); + }, + + // onCompleted + () => { + flush(); + observer.complete(); + }), + + // We know *for certain* that we have a complete entry once we see the metadata for the next + // one. But what if the next one takes a long time to happen? After a certain point, we need + // to just assume we have the complete entry and move on. + sharedLine$.debounceTime(200).subscribe(flush)); + }).map((_createMessage || _load_createMessage()).default); return filter(messages).share(); } -function filter(messages: Observable): Observable { - const patterns = - (featureConfig.observeAsStream('nuclide-adb-logcat.whitelistedTags'): Observable) - .map(source => { - try { - return new RegExp(source); - } catch (err) { - atom.notifications.addError( - 'The nuclide-adb-logcat.whitelistedTags setting contains an invalid regular expression' - + ' string. Fix it in your Atom settings.', - ); - return /.*/; - } - }); - - return messages - .withLatestFrom(patterns) - .filter(([message, pattern]) => { - // Add an empty tag to untagged messages so they cfeaturean be matched by `.*` etc. - const tags = message.tags == null ? [''] : message.tags; - return tags.some(tag => pattern.test(tag)); - }) - .map(([message, pattern]) => message); +function filter(messages) { + const patterns = (_featureConfig || _load_featureConfig()).default.observeAsStream('nuclide-adb-logcat.whitelistedTags').map(source => { + try { + return new RegExp(source); + } catch (err) { + atom.notifications.addError('The nuclide-adb-logcat.whitelistedTags setting contains an invalid regular expression' + ' string. Fix it in your Atom settings.'); + return (/.*/ + ); + } + }); + + return messages.withLatestFrom(patterns).filter(([message, pattern]) => { + // Add an empty tag to untagged messages so they cfeaturean be matched by `.*` etc. + const tags = message.tags == null ? [''] : message.tags; + return tags.some(tag => pattern.test(tag)); + }).map(([message, pattern]) => message); } +module.exports = exports['default']; \ No newline at end of file diff --git a/pkg/nuclide-adb-logcat/lib/createProcessStream.js b/pkg/nuclide-adb-logcat/lib/createProcessStream.js index b88a4715ff..d904140ef7 100644 --- a/pkg/nuclide-adb-logcat/lib/createProcessStream.js +++ b/pkg/nuclide-adb-logcat/lib/createProcessStream.js @@ -1,3 +1,32 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.createProcessStream = createProcessStream; + +var _process; + +function _load_process() { + return _process = require('../../commons-node/process'); +} + +var _observable; + +function _load_observable() { + return _observable = require('../../commons-node/observable'); +} + +var _featureConfig; + +function _load_featureConfig() { + return _featureConfig = _interopRequireDefault(require('../../commons-atom/featureConfig')); +} + +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js'); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,70 +34,53 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * */ -import {observeProcess, safeSpawn} from '../../commons-node/process'; -import {compact} from '../../commons-node/observable'; -import featureConfig from '../../commons-atom/featureConfig'; -import {Observable} from 'rxjs'; - -export function createProcessStream(): Observable { - const processEvents = observeProcess(spawnAdbLogcat).share(); - const stdoutEvents = processEvents - .filter(event => event.kind === 'stdout') - // Not all versions of adb have a way to skip historical logs so we just ignore the first - // second. - .skipUntil(Observable.interval(1000).take(1)); +function createProcessStream() { + const processEvents = (0, (_process || _load_process()).observeProcess)(spawnAdbLogcat).share(); + const stdoutEvents = processEvents.filter(event => event.kind === 'stdout') + // Not all versions of adb have a way to skip historical logs so we just ignore the first + // second. + .skipUntil(_rxjsBundlesRxMinJs.Observable.interval(1000).take(1)); const otherEvents = processEvents.filter(event => event.kind !== 'stdout'); - return compact( - Observable.merge(stdoutEvents, otherEvents) - // Forward the event, but add the last line of std err too. We can use this later if the - // process exits to provide more information. - .scan( - (acc, event) => { - switch (event.kind) { - case 'error': - throw event.error; - case 'exit': - throw new Error(acc.lastError || ''); - case 'stdout': - // Keep track of the last error so that we can show it to users if the process dies - // badly. If we get a non-error message, then the last error we saw wasn't the one - // that killed the process, so throw it away. Why is this not on stderr? I don't know. - return { - event, - lastError: parseError(event.data) || acc.lastError, - }; - case 'stderr': - return { - ...acc, - lastError: event.data || acc.lastError, - event, - }; - default: - // This should never happen. - throw new Error(`Invalid event kind: ${event.kind}`); - } - }, - {event: null, lastError: null}, - ) - .map(acc => acc.event), - ) - // Only get the text from stdout. - .filter(event => event.kind === 'stdout') - .map(event => event.data && event.data.replace(/\r*\n$/, '')); + return (0, (_observable || _load_observable()).compact)(_rxjsBundlesRxMinJs.Observable.merge(stdoutEvents, otherEvents) + // Forward the event, but add the last line of std err too. We can use this later if the + // process exits to provide more information. + .scan((acc, event) => { + switch (event.kind) { + case 'error': + throw event.error; + case 'exit': + throw new Error(acc.lastError || ''); + case 'stdout': + // Keep track of the last error so that we can show it to users if the process dies + // badly. If we get a non-error message, then the last error we saw wasn't the one + // that killed the process, so throw it away. Why is this not on stderr? I don't know. + return { + event, + lastError: parseError(event.data) || acc.lastError + }; + case 'stderr': + return Object.assign({}, acc, { + lastError: event.data || acc.lastError, + event + }); + default: + // This should never happen. + throw new Error(`Invalid event kind: ${event.kind}`); + } + }, { event: null, lastError: null }).map(acc => acc.event)) + // Only get the text from stdout. + .filter(event => event.kind === 'stdout').map(event => event.data && event.data.replace(/\r*\n$/, '')); } -function spawnAdbLogcat(): child_process$ChildProcess { - return safeSpawn( - ((featureConfig.get('nuclide-adb-logcat.pathToAdb'): any): string), - ['logcat', '-v', 'long'], - ); +function spawnAdbLogcat() { + return (0, (_process || _load_process()).safeSpawn)((_featureConfig || _load_featureConfig()).default.get('nuclide-adb-logcat.pathToAdb'), ['logcat', '-v', 'long']); } -function parseError(line: string): ?string { +function parseError(line) { const match = line.match(/^ERROR:\s*(.*)/); return match == null ? null : match[1].trim(); -} +} \ No newline at end of file diff --git a/pkg/nuclide-adb-logcat/lib/main.js b/pkg/nuclide-adb-logcat/lib/main.js index c349dbd511..9eec2e2f39 100644 --- a/pkg/nuclide-adb-logcat/lib/main.js +++ b/pkg/nuclide-adb-logcat/lib/main.js @@ -1,31 +1,47 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the license found in the LICENSE file in - * the root directory of this source tree. - * - * @flow - */ +'use strict'; -import type {OutputService} from '../../nuclide-console/lib/types'; +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.activate = activate; +exports.deactivate = deactivate; +exports.consumeOutputService = consumeOutputService; -import invariant from 'assert'; -import Activation from './Activation'; +var _Activation; -let activation: ?Activation = null; +function _load_Activation() { + return _Activation = _interopRequireDefault(require('./Activation')); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +let activation = null; /** + * Copyright (c) 2015-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the license found in the LICENSE file in + * the root directory of this source tree. + * + * + */ -export function activate(state: ?Object) { - activation = new Activation(state); +function activate(state) { + activation = new (_Activation || _load_Activation()).default(state); } -export function deactivate() { - invariant(activation != null); +function deactivate() { + if (!(activation != null)) { + throw new Error('Invariant violation: "activation != null"'); + } + activation.dispose(); activation = null; } -export function consumeOutputService(api: OutputService): void { - invariant(activation); +function consumeOutputService(api) { + if (!activation) { + throw new Error('Invariant violation: "activation"'); + } + activation.consumeOutputService(api); -} +} \ No newline at end of file diff --git a/pkg/nuclide-adb-logcat/lib/parseLogcatMetadata.js b/pkg/nuclide-adb-logcat/lib/parseLogcatMetadata.js index 01c1b9e8fa..471014779e 100644 --- a/pkg/nuclide-adb-logcat/lib/parseLogcatMetadata.js +++ b/pkg/nuclide-adb-logcat/lib/parseLogcatMetadata.js @@ -1,20 +1,24 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the license found in the LICENSE file in - * the root directory of this source tree. - * - * @flow - */ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = parseLogcatMetadata; -import type {Metadata, Priority} from './types'; // Example: [ 01-14 17:14:44.285 640: 656 E/KernelUidCpuTimeReader ] // eslint-disable-next-line max-len -const METADATA_REGEX = /^\[ (\d{2}-\d{2} \d{2}:\d{2}:\d{2}\.\d{3})\s+(\d+):(?:(0x[a-f0-9]+)|\s+(\d+))\s+(V|D|I|W|E|F|S)\/(.+) ]$/; +const METADATA_REGEX = /^\[ (\d{2}-\d{2} \d{2}:\d{2}:\d{2}\.\d{3})\s+(\d+):(?:(0x[a-f0-9]+)|\s+(\d+))\s+(V|D|I|W|E|F|S)\/(.+) ]$/; /** + * Copyright (c) 2015-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the license found in the LICENSE file in + * the root directory of this source tree. + * + * + */ -export default function parseLogcatMetadata(line: string): ?Metadata { +function parseLogcatMetadata(line) { const match = line.match(METADATA_REGEX); if (match == null) { @@ -27,7 +31,8 @@ export default function parseLogcatMetadata(line: string): ?Metadata { time, pid: parseInt(pid, 10), tid: hexTid == null ? parseInt(decTid, 10) : parseInt(hexTid, 16), - priority: ((priority: any): Priority), - tag, + priority: priority, + tag }; } +module.exports = exports['default']; \ No newline at end of file diff --git a/pkg/nuclide-adb-logcat/lib/types.js b/pkg/nuclide-adb-logcat/lib/types.js index 2002f17c29..a726efc43f 100644 --- a/pkg/nuclide-adb-logcat/lib/types.js +++ b/pkg/nuclide-adb-logcat/lib/types.js @@ -1,24 +1 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the license found in the LICENSE file in - * the root directory of this source tree. - * - * @flow - */ - -export type Priority = 'V' | 'D' | 'I' | 'W' | 'E' | 'F' | 'S'; - -export type LogcatEntry = { - message: string, - metadata: ?Metadata, -}; - -export type Metadata = { - time: string, - pid: number, - tid: number, - priority: Priority, - tag: string, -}; +'use strict'; \ No newline at end of file diff --git a/pkg/nuclide-adb-logcat/spec/createMessageStream-spec.js b/pkg/nuclide-adb-logcat/spec/createMessageStream-spec.js deleted file mode 100644 index fa5c15b782..0000000000 --- a/pkg/nuclide-adb-logcat/spec/createMessageStream-spec.js +++ /dev/null @@ -1,89 +0,0 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the license found in the LICENSE file in - * the root directory of this source tree. - * - * @flow - */ - -import featureConfig from '../../commons-atom/featureConfig'; -import createMessageStream from '../lib/createMessageStream'; -import {Observable} from 'rxjs'; - -describe('createMessageStream', () => { - it('splits the output by message', () => { - const original = featureConfig.observeAsStream.bind(featureConfig); - spyOn(featureConfig, 'observeAsStream').andCallFake(name => ( - name === 'nuclide-adb-logcat.whitelistedTags' ? Observable.of('.*') : original(name) - )); - - waitsForPromise(async () => { - const output = Observable.from([ - '[ 01-14 17:15:01.003 640: 654 I/ProcessStatsService ]', - 'Prepared write state in 0ms', - '', - '[ 01-14 17:15:01.003 640: 654 I/ProcessStatsService ]', - 'Prepared write state in 0ms', - '', - ]); - - const messages = await createMessageStream(output) - .map(message => message.text) - .toArray() - .toPromise(); - - expect(messages.length).toBe(2); - messages.forEach(message => { - expect(message).toBe('Prepared write state in 0ms'); - }); - }); - }); - - it('only includes messages with whitelisted tags', () => { - const original = featureConfig.observeAsStream.bind(featureConfig); - spyOn(featureConfig, 'observeAsStream').andCallFake(name => ( - name === 'nuclide-adb-logcat.whitelistedTags' ? Observable.of('ExampleTag') : original(name) - )); - - waitsForPromise(async () => { - const output = Observable.from([ - '[ 01-14 17:15:01.003 640: 654 I/ProcessStatsService ]', - 'Bad', - '', - '[ 01-14 17:15:01.003 640: 654 I/ExampleTag ]', - 'Good', - '', - ]); - - const messages = await createMessageStream(output) - .map(message => message.text) - .toArray() - .toPromise(); - - expect(messages).toEqual(['Good']); - }); - }); - - it('shows an error (once) if the regular expression is invalid', () => { - spyOn(atom.notifications, 'addError'); - const original = featureConfig.observeAsStream.bind(featureConfig); - spyOn(featureConfig, 'observeAsStream').andCallFake(name => ( - name === 'nuclide-adb-logcat.whitelistedTags' ? Observable.of('(') : original(name) - )); - - waitsForPromise(async () => { - const output = Observable.from([ - '[ 01-14 17:15:01.003 640: 654 I/ProcessStatsService ]', - 'Bad', - '', - '[ 01-14 17:15:01.003 640: 654 I/ExampleTag ]', - 'Good', - '', - ]); - await createMessageStream(output).toPromise(); - expect(atom.notifications.addError.callCount).toBe(1); - }); - }); -}); diff --git a/pkg/nuclide-adb-logcat/spec/parseLogcatMetadata-spec.js b/pkg/nuclide-adb-logcat/spec/parseLogcatMetadata-spec.js deleted file mode 100644 index 36c2fbefae..0000000000 --- a/pkg/nuclide-adb-logcat/spec/parseLogcatMetadata-spec.js +++ /dev/null @@ -1,55 +0,0 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the license found in the LICENSE file in - * the root directory of this source tree. - * - * @flow - */ - -import invariant from 'assert'; -import parseLogcatMetadata from '../lib/parseLogcatMetadata'; - -describe('parseLogcatMetadata', () => { - const formats = [ - '[ 01-14 17:15:01.003 640: 654 I/ProcessStatsService ]', - // Older versions use hex for the tid. - '[ 01-14 17:15:01.003 640:0x28e I/ProcessStatsService ]', - ]; - - formats.forEach(raw => { - describe(raw, () => { - const parsed = parseLogcatMetadata(raw); - invariant(parsed != null); - - it('parses the date and time', () => { - expect(parsed.time).toBe('01-14 17:15:01.003'); - }); - - it('parses the pid', () => { - expect(parsed.pid).toBe(640); - }); - - it('parses the tid', () => { - expect(parsed.tid).toBe(654); - }); - - it('parses the priority', () => { - expect(parsed.priority).toBe('I'); - }); - - it('parses the tag', () => { - expect(parsed.tag).toBe('ProcessStatsService'); - }); - }); - }); - - it('parses weird tags', () => { - const parsed = parseLogcatMetadata( - '[ 05-10 17:49:43.925 5846: 5993 D/fb4a(:):PeriodicForegroundScheduler ]', - ); - invariant(parsed != null); - expect(parsed.tag).toBe('fb4a(:):PeriodicForegroundScheduler'); - }); -}); diff --git a/pkg/nuclide-adb-rpc/lib/ADB.js b/pkg/nuclide-adb-rpc/lib/ADB.js index 53bc5bfeec..2a88935c01 100644 --- a/pkg/nuclide-adb-rpc/lib/ADB.js +++ b/pkg/nuclide-adb-rpc/lib/ADB.js @@ -1,96 +1,120 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the license found in the LICENSE file in - * the root directory of this source tree. - * - * @flow - */ - -import type {Observable, ConnectableObservable} from 'rxjs'; -import type {DeviceDescription} from './AdbService'; -import type {ProcessMessage} from '../../commons-node/process-rpc-types'; -import type {NuclideUri} from '../../commons-node/nuclideUri'; - -import invariant from 'assert'; -import nuclideUri from '../../commons-node/nuclideUri'; -import {safeSpawn, observeProcess, runCommand} from '../../commons-node/process'; - -import * as os from 'os'; - -function runShortAdbCommand( - adbPath: NuclideUri, - device: string, - command: Array, -): Observable { - return runCommand(adbPath, ['-s', device].concat(command)); +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.getPidFromPackageName = exports.getDeviceList = undefined; + +var _asyncToGenerator = _interopRequireDefault(require('async-to-generator')); + +let getDeviceList = exports.getDeviceList = (() => { + var _ref = (0, _asyncToGenerator.default)(function* (adbPath) { + const devices = yield (0, (_process || _load_process()).runCommand)(adbPath, ['devices']).map(function (stdout) { + return stdout.split(/\n+/g).slice(1).filter(function (s) { + return s.length > 0; + }).map(function (s) { + return s.split(/\s+/g); + }).filter(function (a) { + return a[1] !== 'offline'; + }).map(function (a) { + return a[0]; + }); + }).toPromise(); + + return Promise.all(devices.map((() => { + var _ref2 = (0, _asyncToGenerator.default)(function* (name) { + const architecture = yield getDeviceArchitecture(adbPath, name); + const apiVersion = yield getAPIVersion(adbPath, name); + const model = yield getDeviceModel(adbPath, name); + return { name, architecture, apiVersion, model }; + }); + + return function (_x2) { + return _ref2.apply(this, arguments); + }; + })())); + }); + + return function getDeviceList(_x) { + return _ref.apply(this, arguments); + }; +})(); + +let getPidFromPackageName = exports.getPidFromPackageName = (() => { + var _ref3 = (0, _asyncToGenerator.default)(function* (adbPath, packageName) { + const pidLine = (yield (0, (_process || _load_process()).runCommand)(adbPath, ['shell', 'ps', '|', 'grep', '-i', packageName]).toPromise()).split(_os.EOL)[0]; + if (pidLine == null) { + throw new Error(`Can not find a running process with package name: ${packageName}`); + } + // First column is 'USER', second is 'PID'. + return parseInt(pidLine.trim().split(/\s+/)[1], /* radix */10); + }); + + return function getPidFromPackageName(_x3, _x4) { + return _ref3.apply(this, arguments); + }; +})(); + +exports.startServer = startServer; +exports.getDeviceArchitecture = getDeviceArchitecture; +exports.getDeviceModel = getDeviceModel; +exports.getAPIVersion = getAPIVersion; +exports.installPackage = installPackage; +exports.uninstallPackage = uninstallPackage; +exports.forwardJdwpPortToPid = forwardJdwpPortToPid; + +var _nuclideUri; + +function _load_nuclideUri() { + return _nuclideUri = _interopRequireDefault(require('../../commons-node/nuclideUri')); } -function runLongAdbCommand( - adbPath: NuclideUri, - device: string, - command: string[], -): Observable { - return observeProcess(() => safeSpawn(adbPath, ['-s', device].concat(command)), true); -} +var _process; -function getAndroidProp( - adbPath: NuclideUri, - device: string, - key: string, -): Observable { - return runShortAdbCommand(adbPath, device, ['shell', 'getprop', key]) - .map(s => s.trim()); +function _load_process() { + return _process = require('../../commons-node/process'); } -function getTizenModelConfigKey( - adbPath: NuclideUri, - device: string, - key: string, -): Promise { - const modelConfigPath = '/etc/config/model-config.xml'; +var _os = _interopRequireWildcard(require('os')); + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } } + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - return runShortAdbCommand(adbPath, device, ['shell', 'cat', modelConfigPath]) - .map(stdout => stdout.split(/\n+/g) - .filter(s => s.indexOf(key) !== -1)[0]) - .map(s => { - const regex = /.*<.*>(.*)<.*>/g; - return regex.exec(s)[1]; - }) - .toPromise(); +function runShortAdbCommand(adbPath, device, command) { + return (0, (_process || _load_process()).runCommand)(adbPath, ['-s', device].concat(command)); +} /** + * Copyright (c) 2015-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the license found in the LICENSE file in + * the root directory of this source tree. + * + * + */ + +function runLongAdbCommand(adbPath, device, command) { + return (0, (_process || _load_process()).observeProcess)(() => (0, (_process || _load_process()).safeSpawn)(adbPath, ['-s', device].concat(command)), true); } -export function startServer( - adbPath: NuclideUri, -): ConnectableObservable { - return runCommand(adbPath, ['start-server']).publish(); +function getAndroidProp(adbPath, device, key) { + return runShortAdbCommand(adbPath, device, ['shell', 'getprop', key]).map(s => s.trim()); } -export async function getDeviceList( - adbPath: NuclideUri, -): Promise> { - const devices = await runCommand(adbPath, ['devices']) - .map(stdout => stdout.split(/\n+/g) - .slice(1) - .filter(s => s.length > 0) - .map(s => s.split(/\s+/g)) - .filter(a => a[1] !== 'offline') - .map(a => a[0])) - .toPromise(); - - return Promise.all(devices.map(async name => { - const architecture = await getDeviceArchitecture(adbPath, name); - const apiVersion = await getAPIVersion(adbPath, name); - const model = await getDeviceModel(adbPath, name); - return {name, architecture, apiVersion, model}; - })); +function getTizenModelConfigKey(adbPath, device, key) { + const modelConfigPath = '/etc/config/model-config.xml'; + + return runShortAdbCommand(adbPath, device, ['shell', 'cat', modelConfigPath]).map(stdout => stdout.split(/\n+/g).filter(s => s.indexOf(key) !== -1)[0]).map(s => { + const regex = /.*<.*>(.*)<.*>/g; + return regex.exec(s)[1]; + }).toPromise(); } -export function getDeviceArchitecture( - adbPath: NuclideUri, - device: string, -): Promise { +function startServer(adbPath) { + return (0, (_process || _load_process()).runCommand)(adbPath, ['start-server']).publish(); +} + +function getDeviceArchitecture(adbPath, device) { // SDB is a tool similar to ADB used with Tizen devices. `getprop` doesn't // exist on Tizen, so we have to rely on uname instead. if (adbPath.endsWith('sdb')) { @@ -100,23 +124,15 @@ export function getDeviceArchitecture( } } -export function getDeviceModel( - adbPath: NuclideUri, - device: string, -): Promise { +function getDeviceModel(adbPath, device) { if (adbPath.endsWith('sdb')) { return getTizenModelConfigKey(adbPath, device, 'tizen.org/system/model_name'); } else { - return getAndroidProp(adbPath, device, 'ro.product.model') - .map(s => (s === 'sdk' ? 'emulator' : s)) - .toPromise(); + return getAndroidProp(adbPath, device, 'ro.product.model').map(s => s === 'sdk' ? 'emulator' : s).toPromise(); } } -export function getAPIVersion( - adbPath: NuclideUri, - device: string, -): Promise { +function getAPIVersion(adbPath, device) { if (adbPath.endsWith('sdb')) { return getTizenModelConfigKey(adbPath, device, 'tizen.org/feature/platform.core.api.version'); } else { @@ -124,45 +140,18 @@ export function getAPIVersion( } } -export function installPackage( - adbPath: NuclideUri, - device: string, - packagePath: NuclideUri, -): Observable { - invariant(!nuclideUri.isRemote(packagePath)); +function installPackage(adbPath, device, packagePath) { + if (!!(_nuclideUri || _load_nuclideUri()).default.isRemote(packagePath)) { + throw new Error('Invariant violation: "!nuclideUri.isRemote(packagePath)"'); + } + return runLongAdbCommand(adbPath, device, ['install', packagePath]); } -export function uninstallPackage( - adbPath: NuclideUri, - device: string, - packageName: string, -): Observable { +function uninstallPackage(adbPath, device, packageName) { return runLongAdbCommand(adbPath, device, ['uninstall', packageName]); } -export async function getPidFromPackageName( - adbPath: NuclideUri, - packageName: string, -): Promise { - const pidLine = (await runCommand( - adbPath, - ['shell', 'ps', '|', 'grep', '-i', packageName], - ).toPromise()).split(os.EOL)[0]; - if (pidLine == null) { - throw new Error(`Can not find a running process with package name: ${packageName}`); - } - // First column is 'USER', second is 'PID'. - return parseInt(pidLine.trim().split(/\s+/)[1], /* radix */10); -} - -export function forwardJdwpPortToPid( - adbPath: NuclideUri, - tcpPort: number, - pid: number, -): Promise { - return runCommand( - adbPath, - ['forward', `tcp:${tcpPort}`, `jdwp:${pid}`], - ).toPromise(); -} +function forwardJdwpPortToPid(adbPath, tcpPort, pid) { + return (0, (_process || _load_process()).runCommand)(adbPath, ['forward', `tcp:${tcpPort}`, `jdwp:${pid}`]).toPromise(); +} \ No newline at end of file diff --git a/pkg/nuclide-adb-rpc/lib/AdbService.js b/pkg/nuclide-adb-rpc/lib/AdbService.js index 4ec5b6a819..a5704023f6 100644 --- a/pkg/nuclide-adb-rpc/lib/AdbService.js +++ b/pkg/nuclide-adb-rpc/lib/AdbService.js @@ -1,3 +1,26 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.startServer = startServer; +exports.getDeviceList = getDeviceList; +exports.getDeviceArchitecture = getDeviceArchitecture; +exports.getDeviceModel = getDeviceModel; +exports.getAPIVersion = getAPIVersion; +exports.installPackage = installPackage; +exports.uninstallPackage = uninstallPackage; +exports.getPidFromPackageName = getPidFromPackageName; +exports.forwardJdwpPortToPid = forwardJdwpPortToPid; + +var _ADB; + +function _load_ADB() { + return _ADB = _interopRequireWildcard(require('./ADB')); +} + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } } + /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,82 +28,41 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * */ -import type {NuclideUri} from '../../commons-node/nuclideUri'; -import type {ConnectableObservable} from 'rxjs'; -import type {ProcessMessage} from '../../commons-node/process-rpc-types'; - -import * as ADB from './ADB'; - -export type DeviceDescription = { - name: string, - architecture: string, - apiVersion: string, - model: string, -}; - -export function startServer( - adbPath: NuclideUri, -): ConnectableObservable { - return ADB.startServer(adbPath); +function startServer(adbPath) { + return (_ADB || _load_ADB()).startServer(adbPath); } -export function getDeviceList( - adbPath: NuclideUri, -): Promise> { - return ADB.getDeviceList(adbPath); +function getDeviceList(adbPath) { + return (_ADB || _load_ADB()).getDeviceList(adbPath); } -export function getDeviceArchitecture( - adbPath: NuclideUri, - device: string, -): Promise { - return ADB.getDeviceArchitecture(adbPath, device); +function getDeviceArchitecture(adbPath, device) { + return (_ADB || _load_ADB()).getDeviceArchitecture(adbPath, device); } -export function getDeviceModel( - adbPath: NuclideUri, - device: string, -): Promise { - return ADB.getDeviceModel(adbPath, device); +function getDeviceModel(adbPath, device) { + return (_ADB || _load_ADB()).getDeviceModel(adbPath, device); } -export function getAPIVersion( - adbPath: NuclideUri, - device: string, -): Promise { - return ADB.getAPIVersion(adbPath, device); +function getAPIVersion(adbPath, device) { + return (_ADB || _load_ADB()).getAPIVersion(adbPath, device); } -export function installPackage( - adbPath: NuclideUri, - device: string, - packagePath: NuclideUri, -): ConnectableObservable { - return ADB.installPackage(adbPath, device, packagePath).publish(); +function installPackage(adbPath, device, packagePath) { + return (_ADB || _load_ADB()).installPackage(adbPath, device, packagePath).publish(); } -export function uninstallPackage( - adbPath: NuclideUri, - device: string, - packageName: string, -): ConnectableObservable { - return ADB.uninstallPackage(adbPath, device, packageName).publish(); +function uninstallPackage(adbPath, device, packageName) { + return (_ADB || _load_ADB()).uninstallPackage(adbPath, device, packageName).publish(); } -export function getPidFromPackageName( - adbPath: NuclideUri, - packageName: string, -): Promise { - return ADB.getPidFromPackageName(adbPath, packageName); +function getPidFromPackageName(adbPath, packageName) { + return (_ADB || _load_ADB()).getPidFromPackageName(adbPath, packageName); } -export function forwardJdwpPortToPid( - adbPath: NuclideUri, - tcpPort: number, - pid: number, -): Promise { - return ADB.forwardJdwpPortToPid(adbPath, tcpPort, pid); -} +function forwardJdwpPortToPid(adbPath, tcpPort, pid) { + return (_ADB || _load_ADB()).forwardJdwpPortToPid(adbPath, tcpPort, pid); +} \ No newline at end of file diff --git a/pkg/nuclide-adb-rpc/lib/AdbServiceProxy.js b/pkg/nuclide-adb-rpc/lib/AdbServiceProxy.js new file mode 100644 index 0000000000..01736c65bf --- /dev/null +++ b/pkg/nuclide-adb-rpc/lib/AdbServiceProxy.js @@ -0,0 +1,1363 @@ +"use strict"; + +let Observable; + +module.exports = _client => { + const remoteModule = {}; + + remoteModule.startServer = function (arg0) { + return Observable.fromPromise(_client.marshalArguments(Array.from(arguments), [{ + name: "adbPath", + type: { + location: { + type: "source", + fileName: "AdbService.js", + line: 25 + }, + kind: "named", + name: "NuclideUri" + } + }]).then(args => { + return _client.callRemoteFunction("AdbService/startServer", "observable", args); + })).concatMap(id => id).concatMap(value => { + return _client.unmarshal(value, { + location: { + type: "source", + fileName: "AdbService.js", + line: 26 + }, + kind: "string" + }); + }).publish(); + }; + + remoteModule.getDeviceList = function (arg0) { + return _client.marshalArguments(Array.from(arguments), [{ + name: "adbPath", + type: { + location: { + type: "source", + fileName: "AdbService.js", + line: 31 + }, + kind: "named", + name: "NuclideUri" + } + }]).then(args => { + return _client.callRemoteFunction("AdbService/getDeviceList", "promise", args); + }).then(value => { + return _client.unmarshal(value, { + location: { + type: "source", + fileName: "AdbService.js", + line: 32 + }, + kind: "array", + type: { + location: { + type: "source", + fileName: "AdbService.js", + line: 32 + }, + kind: "named", + name: "DeviceDescription" + } + }); + }); + }; + + remoteModule.getDeviceArchitecture = function (arg0, arg1) { + return _client.marshalArguments(Array.from(arguments), [{ + name: "adbPath", + type: { + location: { + type: "source", + fileName: "AdbService.js", + line: 37 + }, + kind: "named", + name: "NuclideUri" + } + }, { + name: "device", + type: { + location: { + type: "source", + fileName: "AdbService.js", + line: 38 + }, + kind: "string" + } + }]).then(args => { + return _client.callRemoteFunction("AdbService/getDeviceArchitecture", "promise", args); + }).then(value => { + return _client.unmarshal(value, { + location: { + type: "source", + fileName: "AdbService.js", + line: 39 + }, + kind: "string" + }); + }); + }; + + remoteModule.getDeviceModel = function (arg0, arg1) { + return _client.marshalArguments(Array.from(arguments), [{ + name: "adbPath", + type: { + location: { + type: "source", + fileName: "AdbService.js", + line: 44 + }, + kind: "named", + name: "NuclideUri" + } + }, { + name: "device", + type: { + location: { + type: "source", + fileName: "AdbService.js", + line: 45 + }, + kind: "string" + } + }]).then(args => { + return _client.callRemoteFunction("AdbService/getDeviceModel", "promise", args); + }).then(value => { + return _client.unmarshal(value, { + location: { + type: "source", + fileName: "AdbService.js", + line: 46 + }, + kind: "string" + }); + }); + }; + + remoteModule.getAPIVersion = function (arg0, arg1) { + return _client.marshalArguments(Array.from(arguments), [{ + name: "adbPath", + type: { + location: { + type: "source", + fileName: "AdbService.js", + line: 51 + }, + kind: "named", + name: "NuclideUri" + } + }, { + name: "device", + type: { + location: { + type: "source", + fileName: "AdbService.js", + line: 52 + }, + kind: "string" + } + }]).then(args => { + return _client.callRemoteFunction("AdbService/getAPIVersion", "promise", args); + }).then(value => { + return _client.unmarshal(value, { + location: { + type: "source", + fileName: "AdbService.js", + line: 53 + }, + kind: "string" + }); + }); + }; + + remoteModule.installPackage = function (arg0, arg1, arg2) { + return Observable.fromPromise(_client.marshalArguments(Array.from(arguments), [{ + name: "adbPath", + type: { + location: { + type: "source", + fileName: "AdbService.js", + line: 58 + }, + kind: "named", + name: "NuclideUri" + } + }, { + name: "device", + type: { + location: { + type: "source", + fileName: "AdbService.js", + line: 59 + }, + kind: "string" + } + }, { + name: "packagePath", + type: { + location: { + type: "source", + fileName: "AdbService.js", + line: 60 + }, + kind: "named", + name: "NuclideUri" + } + }]).then(args => { + return _client.callRemoteFunction("AdbService/installPackage", "observable", args); + })).concatMap(id => id).concatMap(value => { + return _client.unmarshal(value, { + location: { + type: "source", + fileName: "AdbService.js", + line: 61 + }, + kind: "named", + name: "ProcessMessage" + }); + }).publish(); + }; + + remoteModule.uninstallPackage = function (arg0, arg1, arg2) { + return Observable.fromPromise(_client.marshalArguments(Array.from(arguments), [{ + name: "adbPath", + type: { + location: { + type: "source", + fileName: "AdbService.js", + line: 66 + }, + kind: "named", + name: "NuclideUri" + } + }, { + name: "device", + type: { + location: { + type: "source", + fileName: "AdbService.js", + line: 67 + }, + kind: "string" + } + }, { + name: "packageName", + type: { + location: { + type: "source", + fileName: "AdbService.js", + line: 68 + }, + kind: "string" + } + }]).then(args => { + return _client.callRemoteFunction("AdbService/uninstallPackage", "observable", args); + })).concatMap(id => id).concatMap(value => { + return _client.unmarshal(value, { + location: { + type: "source", + fileName: "AdbService.js", + line: 69 + }, + kind: "named", + name: "ProcessMessage" + }); + }).publish(); + }; + + remoteModule.getPidFromPackageName = function (arg0, arg1) { + return _client.marshalArguments(Array.from(arguments), [{ + name: "adbPath", + type: { + location: { + type: "source", + fileName: "AdbService.js", + line: 74 + }, + kind: "named", + name: "NuclideUri" + } + }, { + name: "packageName", + type: { + location: { + type: "source", + fileName: "AdbService.js", + line: 75 + }, + kind: "string" + } + }]).then(args => { + return _client.callRemoteFunction("AdbService/getPidFromPackageName", "promise", args); + }).then(value => { + return _client.unmarshal(value, { + location: { + type: "source", + fileName: "AdbService.js", + line: 76 + }, + kind: "number" + }); + }); + }; + + remoteModule.forwardJdwpPortToPid = function (arg0, arg1, arg2) { + return _client.marshalArguments(Array.from(arguments), [{ + name: "adbPath", + type: { + location: { + type: "source", + fileName: "AdbService.js", + line: 81 + }, + kind: "named", + name: "NuclideUri" + } + }, { + name: "tcpPort", + type: { + location: { + type: "source", + fileName: "AdbService.js", + line: 82 + }, + kind: "number" + } + }, { + name: "pid", + type: { + location: { + type: "source", + fileName: "AdbService.js", + line: 83 + }, + kind: "number" + } + }]).then(args => { + return _client.callRemoteFunction("AdbService/forwardJdwpPortToPid", "promise", args); + }).then(value => { + return _client.unmarshal(value, { + location: { + type: "source", + fileName: "AdbService.js", + line: 84 + }, + kind: "string" + }); + }); + }; + + return remoteModule; +}; + +Object.defineProperty(module.exports, "inject", { + value: function () { + Observable = arguments[0]; + } +}); +Object.defineProperty(module.exports, "defs", { + value: new Map([["Object", { + kind: "alias", + name: "Object", + location: { + type: "builtin" + } + }], ["Date", { + kind: "alias", + name: "Date", + location: { + type: "builtin" + } + }], ["RegExp", { + kind: "alias", + name: "RegExp", + location: { + type: "builtin" + } + }], ["Buffer", { + kind: "alias", + name: "Buffer", + location: { + type: "builtin" + } + }], ["fs.Stats", { + kind: "alias", + name: "fs.Stats", + location: { + type: "builtin" + } + }], ["NuclideUri", { + kind: "alias", + name: "NuclideUri", + location: { + type: "builtin" + } + }], ["atom$Point", { + kind: "alias", + name: "atom$Point", + location: { + type: "builtin" + } + }], ["atom$Range", { + kind: "alias", + name: "atom$Range", + location: { + type: "builtin" + } + }], ["DeviceDescription", { + kind: "alias", + location: { + type: "source", + fileName: "AdbService.js", + line: 17 + }, + name: "DeviceDescription", + definition: { + location: { + type: "source", + fileName: "AdbService.js", + line: 17 + }, + kind: "object", + fields: [{ + location: { + type: "source", + fileName: "AdbService.js", + line: 18 + }, + name: "name", + type: { + location: { + type: "source", + fileName: "AdbService.js", + line: 18 + }, + kind: "string" + }, + optional: false + }, { + location: { + type: "source", + fileName: "AdbService.js", + line: 19 + }, + name: "architecture", + type: { + location: { + type: "source", + fileName: "AdbService.js", + line: 19 + }, + kind: "string" + }, + optional: false + }, { + location: { + type: "source", + fileName: "AdbService.js", + line: 20 + }, + name: "apiVersion", + type: { + location: { + type: "source", + fileName: "AdbService.js", + line: 20 + }, + kind: "string" + }, + optional: false + }, { + location: { + type: "source", + fileName: "AdbService.js", + line: 21 + }, + name: "model", + type: { + location: { + type: "source", + fileName: "AdbService.js", + line: 21 + }, + kind: "string" + }, + optional: false + }] + } + }], ["startServer", { + kind: "function", + name: "startServer", + location: { + type: "source", + fileName: "AdbService.js", + line: 24 + }, + type: { + location: { + type: "source", + fileName: "AdbService.js", + line: 24 + }, + kind: "function", + argumentTypes: [{ + name: "adbPath", + type: { + location: { + type: "source", + fileName: "AdbService.js", + line: 25 + }, + kind: "named", + name: "NuclideUri" + } + }], + returnType: { + location: { + type: "source", + fileName: "AdbService.js", + line: 26 + }, + kind: "observable", + type: { + location: { + type: "source", + fileName: "AdbService.js", + line: 26 + }, + kind: "string" + } + } + } + }], ["getDeviceList", { + kind: "function", + name: "getDeviceList", + location: { + type: "source", + fileName: "AdbService.js", + line: 30 + }, + type: { + location: { + type: "source", + fileName: "AdbService.js", + line: 30 + }, + kind: "function", + argumentTypes: [{ + name: "adbPath", + type: { + location: { + type: "source", + fileName: "AdbService.js", + line: 31 + }, + kind: "named", + name: "NuclideUri" + } + }], + returnType: { + location: { + type: "source", + fileName: "AdbService.js", + line: 32 + }, + kind: "promise", + type: { + location: { + type: "source", + fileName: "AdbService.js", + line: 32 + }, + kind: "array", + type: { + location: { + type: "source", + fileName: "AdbService.js", + line: 32 + }, + kind: "named", + name: "DeviceDescription" + } + } + } + } + }], ["getDeviceArchitecture", { + kind: "function", + name: "getDeviceArchitecture", + location: { + type: "source", + fileName: "AdbService.js", + line: 36 + }, + type: { + location: { + type: "source", + fileName: "AdbService.js", + line: 36 + }, + kind: "function", + argumentTypes: [{ + name: "adbPath", + type: { + location: { + type: "source", + fileName: "AdbService.js", + line: 37 + }, + kind: "named", + name: "NuclideUri" + } + }, { + name: "device", + type: { + location: { + type: "source", + fileName: "AdbService.js", + line: 38 + }, + kind: "string" + } + }], + returnType: { + location: { + type: "source", + fileName: "AdbService.js", + line: 39 + }, + kind: "promise", + type: { + location: { + type: "source", + fileName: "AdbService.js", + line: 39 + }, + kind: "string" + } + } + } + }], ["getDeviceModel", { + kind: "function", + name: "getDeviceModel", + location: { + type: "source", + fileName: "AdbService.js", + line: 43 + }, + type: { + location: { + type: "source", + fileName: "AdbService.js", + line: 43 + }, + kind: "function", + argumentTypes: [{ + name: "adbPath", + type: { + location: { + type: "source", + fileName: "AdbService.js", + line: 44 + }, + kind: "named", + name: "NuclideUri" + } + }, { + name: "device", + type: { + location: { + type: "source", + fileName: "AdbService.js", + line: 45 + }, + kind: "string" + } + }], + returnType: { + location: { + type: "source", + fileName: "AdbService.js", + line: 46 + }, + kind: "promise", + type: { + location: { + type: "source", + fileName: "AdbService.js", + line: 46 + }, + kind: "string" + } + } + } + }], ["getAPIVersion", { + kind: "function", + name: "getAPIVersion", + location: { + type: "source", + fileName: "AdbService.js", + line: 50 + }, + type: { + location: { + type: "source", + fileName: "AdbService.js", + line: 50 + }, + kind: "function", + argumentTypes: [{ + name: "adbPath", + type: { + location: { + type: "source", + fileName: "AdbService.js", + line: 51 + }, + kind: "named", + name: "NuclideUri" + } + }, { + name: "device", + type: { + location: { + type: "source", + fileName: "AdbService.js", + line: 52 + }, + kind: "string" + } + }], + returnType: { + location: { + type: "source", + fileName: "AdbService.js", + line: 53 + }, + kind: "promise", + type: { + location: { + type: "source", + fileName: "AdbService.js", + line: 53 + }, + kind: "string" + } + } + } + }], ["installPackage", { + kind: "function", + name: "installPackage", + location: { + type: "source", + fileName: "AdbService.js", + line: 57 + }, + type: { + location: { + type: "source", + fileName: "AdbService.js", + line: 57 + }, + kind: "function", + argumentTypes: [{ + name: "adbPath", + type: { + location: { + type: "source", + fileName: "AdbService.js", + line: 58 + }, + kind: "named", + name: "NuclideUri" + } + }, { + name: "device", + type: { + location: { + type: "source", + fileName: "AdbService.js", + line: 59 + }, + kind: "string" + } + }, { + name: "packagePath", + type: { + location: { + type: "source", + fileName: "AdbService.js", + line: 60 + }, + kind: "named", + name: "NuclideUri" + } + }], + returnType: { + location: { + type: "source", + fileName: "AdbService.js", + line: 61 + }, + kind: "observable", + type: { + location: { + type: "source", + fileName: "AdbService.js", + line: 61 + }, + kind: "named", + name: "ProcessMessage" + } + } + } + }], ["uninstallPackage", { + kind: "function", + name: "uninstallPackage", + location: { + type: "source", + fileName: "AdbService.js", + line: 65 + }, + type: { + location: { + type: "source", + fileName: "AdbService.js", + line: 65 + }, + kind: "function", + argumentTypes: [{ + name: "adbPath", + type: { + location: { + type: "source", + fileName: "AdbService.js", + line: 66 + }, + kind: "named", + name: "NuclideUri" + } + }, { + name: "device", + type: { + location: { + type: "source", + fileName: "AdbService.js", + line: 67 + }, + kind: "string" + } + }, { + name: "packageName", + type: { + location: { + type: "source", + fileName: "AdbService.js", + line: 68 + }, + kind: "string" + } + }], + returnType: { + location: { + type: "source", + fileName: "AdbService.js", + line: 69 + }, + kind: "observable", + type: { + location: { + type: "source", + fileName: "AdbService.js", + line: 69 + }, + kind: "named", + name: "ProcessMessage" + } + } + } + }], ["getPidFromPackageName", { + kind: "function", + name: "getPidFromPackageName", + location: { + type: "source", + fileName: "AdbService.js", + line: 73 + }, + type: { + location: { + type: "source", + fileName: "AdbService.js", + line: 73 + }, + kind: "function", + argumentTypes: [{ + name: "adbPath", + type: { + location: { + type: "source", + fileName: "AdbService.js", + line: 74 + }, + kind: "named", + name: "NuclideUri" + } + }, { + name: "packageName", + type: { + location: { + type: "source", + fileName: "AdbService.js", + line: 75 + }, + kind: "string" + } + }], + returnType: { + location: { + type: "source", + fileName: "AdbService.js", + line: 76 + }, + kind: "promise", + type: { + location: { + type: "source", + fileName: "AdbService.js", + line: 76 + }, + kind: "number" + } + } + } + }], ["forwardJdwpPortToPid", { + kind: "function", + name: "forwardJdwpPortToPid", + location: { + type: "source", + fileName: "AdbService.js", + line: 80 + }, + type: { + location: { + type: "source", + fileName: "AdbService.js", + line: 80 + }, + kind: "function", + argumentTypes: [{ + name: "adbPath", + type: { + location: { + type: "source", + fileName: "AdbService.js", + line: 81 + }, + kind: "named", + name: "NuclideUri" + } + }, { + name: "tcpPort", + type: { + location: { + type: "source", + fileName: "AdbService.js", + line: 82 + }, + kind: "number" + } + }, { + name: "pid", + type: { + location: { + type: "source", + fileName: "AdbService.js", + line: 83 + }, + kind: "number" + } + }], + returnType: { + location: { + type: "source", + fileName: "AdbService.js", + line: 84 + }, + kind: "promise", + type: { + location: { + type: "source", + fileName: "AdbService.js", + line: 84 + }, + kind: "string" + } + } + } + }], ["ProcessExitMessage", { + kind: "alias", + location: { + type: "source", + fileName: "process-rpc-types.js", + line: 13 + }, + name: "ProcessExitMessage", + definition: { + location: { + type: "source", + fileName: "process-rpc-types.js", + line: 13 + }, + kind: "object", + fields: [{ + location: { + type: "source", + fileName: "process-rpc-types.js", + line: 14 + }, + name: "kind", + type: { + location: { + type: "source", + fileName: "process-rpc-types.js", + line: 14 + }, + kind: "string-literal", + value: "exit" + }, + optional: false + }, { + location: { + type: "source", + fileName: "process-rpc-types.js", + line: 15 + }, + name: "exitCode", + type: { + location: { + type: "source", + fileName: "process-rpc-types.js", + line: 15 + }, + kind: "nullable", + type: { + location: { + type: "source", + fileName: "process-rpc-types.js", + line: 15 + }, + kind: "number" + } + }, + optional: false + }, { + location: { + type: "source", + fileName: "process-rpc-types.js", + line: 16 + }, + name: "signal", + type: { + location: { + type: "source", + fileName: "process-rpc-types.js", + line: 16 + }, + kind: "nullable", + type: { + location: { + type: "source", + fileName: "process-rpc-types.js", + line: 16 + }, + kind: "string" + } + }, + optional: false + }] + } + }], ["ProcessMessage", { + kind: "alias", + location: { + type: "source", + fileName: "process-rpc-types.js", + line: 20 + }, + name: "ProcessMessage", + definition: { + location: { + type: "source", + fileName: "process-rpc-types.js", + line: 20 + }, + kind: "union", + types: [{ + location: { + type: "source", + fileName: "process-rpc-types.js", + line: 20 + }, + kind: "object", + fields: [{ + location: { + type: "source", + fileName: "process-rpc-types.js", + line: 21 + }, + name: "kind", + type: { + location: { + type: "source", + fileName: "process-rpc-types.js", + line: 21 + }, + kind: "string-literal", + value: "stdout" + }, + optional: false + }, { + location: { + type: "source", + fileName: "process-rpc-types.js", + line: 22 + }, + name: "data", + type: { + location: { + type: "source", + fileName: "process-rpc-types.js", + line: 22 + }, + kind: "string" + }, + optional: false + }] + }, { + location: { + type: "source", + fileName: "process-rpc-types.js", + line: 23 + }, + kind: "object", + fields: [{ + location: { + type: "source", + fileName: "process-rpc-types.js", + line: 24 + }, + name: "kind", + type: { + location: { + type: "source", + fileName: "process-rpc-types.js", + line: 24 + }, + kind: "string-literal", + value: "stderr" + }, + optional: false + }, { + location: { + type: "source", + fileName: "process-rpc-types.js", + line: 25 + }, + name: "data", + type: { + location: { + type: "source", + fileName: "process-rpc-types.js", + line: 25 + }, + kind: "string" + }, + optional: false + }] + }, { + location: { + type: "source", + fileName: "process-rpc-types.js", + line: 13 + }, + kind: "object", + fields: [{ + location: { + type: "source", + fileName: "process-rpc-types.js", + line: 14 + }, + name: "kind", + type: { + location: { + type: "source", + fileName: "process-rpc-types.js", + line: 14 + }, + kind: "string-literal", + value: "exit" + }, + optional: false + }, { + location: { + type: "source", + fileName: "process-rpc-types.js", + line: 15 + }, + name: "exitCode", + type: { + location: { + type: "source", + fileName: "process-rpc-types.js", + line: 15 + }, + kind: "nullable", + type: { + location: { + type: "source", + fileName: "process-rpc-types.js", + line: 15 + }, + kind: "number" + } + }, + optional: false + }, { + location: { + type: "source", + fileName: "process-rpc-types.js", + line: 16 + }, + name: "signal", + type: { + location: { + type: "source", + fileName: "process-rpc-types.js", + line: 16 + }, + kind: "nullable", + type: { + location: { + type: "source", + fileName: "process-rpc-types.js", + line: 16 + }, + kind: "string" + } + }, + optional: false + }] + }, { + location: { + type: "source", + fileName: "process-rpc-types.js", + line: 26 + }, + kind: "object", + fields: [{ + location: { + type: "source", + fileName: "process-rpc-types.js", + line: 27 + }, + name: "kind", + type: { + location: { + type: "source", + fileName: "process-rpc-types.js", + line: 27 + }, + kind: "string-literal", + value: "error" + }, + optional: false + }, { + location: { + type: "source", + fileName: "process-rpc-types.js", + line: 28 + }, + name: "error", + type: { + location: { + type: "source", + fileName: "process-rpc-types.js", + line: 28 + }, + kind: "named", + name: "Object" + }, + optional: false + }] + }], + discriminantField: "kind" + } + }], ["ProcessInfo", { + kind: "alias", + location: { + type: "source", + fileName: "process-rpc-types.js", + line: 31 + }, + name: "ProcessInfo", + definition: { + location: { + type: "source", + fileName: "process-rpc-types.js", + line: 31 + }, + kind: "object", + fields: [{ + location: { + type: "source", + fileName: "process-rpc-types.js", + line: 32 + }, + name: "parentPid", + type: { + location: { + type: "source", + fileName: "process-rpc-types.js", + line: 32 + }, + kind: "number" + }, + optional: false + }, { + location: { + type: "source", + fileName: "process-rpc-types.js", + line: 33 + }, + name: "pid", + type: { + location: { + type: "source", + fileName: "process-rpc-types.js", + line: 33 + }, + kind: "number" + }, + optional: false + }, { + location: { + type: "source", + fileName: "process-rpc-types.js", + line: 34 + }, + name: "command", + type: { + location: { + type: "source", + fileName: "process-rpc-types.js", + line: 34 + }, + kind: "string" + }, + optional: false + }] + } + }]]) +}); \ No newline at end of file diff --git a/pkg/nuclide-analytics/lib/AnalyticsBatcher.js b/pkg/nuclide-analytics/lib/AnalyticsBatcher.js index 8af4407bed..e8c2ab5cb4 100644 --- a/pkg/nuclide-analytics/lib/AnalyticsBatcher.js +++ b/pkg/nuclide-analytics/lib/AnalyticsBatcher.js @@ -1,3 +1,18 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.AnalyticsBatcher = undefined; + +var _BatchProcessedQueue; + +function _load_BatchProcessedQueue() { + return _BatchProcessedQueue = _interopRequireDefault(require('../../commons-node/BatchProcessedQueue')); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,39 +20,30 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * */ -import type {TrackEvent} from './track'; - -import BatchProcessedQueue from '../../commons-node/BatchProcessedQueue'; - const REPORTING_PERIOD = 1000; -type TrackCallback = (events: Array) => mixed; - -export class AnalyticsBatcher { - _queue: BatchProcessedQueue; - _track: TrackCallback; +class AnalyticsBatcher { - constructor(track: TrackCallback) { + constructor(track) { this._track = track; - this._queue = new BatchProcessedQueue( - REPORTING_PERIOD, - events => { - this._handleBatch(events); - }); + this._queue = new (_BatchProcessedQueue || _load_BatchProcessedQueue()).default(REPORTING_PERIOD, events => { + this._handleBatch(events); + }); } - _handleBatch(events: Array): void { + _handleBatch(events) { this._track(events); } - track(key: string, values: {[key: string]: mixed}): void { - this._queue.add({key, values}); + track(key, values) { + this._queue.add({ key, values }); } - dispose(): void { + dispose() { this._queue.dispose(); } } +exports.AnalyticsBatcher = AnalyticsBatcher; \ No newline at end of file diff --git a/pkg/nuclide-analytics/lib/HistogramTracker.js b/pkg/nuclide-analytics/lib/HistogramTracker.js index 0dbafc7a54..bc7b651ae4 100644 --- a/pkg/nuclide-analytics/lib/HistogramTracker.js +++ b/pkg/nuclide-analytics/lib/HistogramTracker.js @@ -1,58 +1,55 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the license found in the LICENSE file in - * the root directory of this source tree. - * - * @flow - */ +'use strict'; -import {track} from './track'; +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.HistogramTracker = undefined; -const HISTOGRAM_TRACKER_KEY = 'performance-histogram'; +var _track; + +function _load_track() { + return _track = require('./track'); +} + +const HISTOGRAM_TRACKER_KEY = 'performance-histogram'; /** + * Copyright (c) 2015-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the license found in the LICENSE file in + * the root directory of this source tree. + * + * + */ class Bucket { - _count: number; - _sum: number; constructor() { this._count = 0; this._sum = 0; } - addValue(value: number): void { + addValue(value) { this._sum += value; this._count++; } - getCount(): number { + getCount() { return this._count; } - getAverage(): number { + getAverage() { return this._count > 0 ? this._sum / this._count : 0; } - clear(): void { + clear() { this._count = 0; this._sum = 0; } } -export class HistogramTracker { - _eventName: string; - _maxValue: number; - _bucketSize: number; - _buckets: Array; - _intervalId: number; - - constructor( - eventName: string, - maxValue: number, - numBuckets: number, - intervalSeconds: number = 60, - ) { +class HistogramTracker { + + constructor(eventName, maxValue, numBuckets, intervalSeconds = 60) { this._eventName = eventName; this._maxValue = maxValue; this._bucketSize = maxValue / numBuckets; @@ -71,29 +68,30 @@ export class HistogramTracker { clearInterval(this._intervalId); } - track(value: number): HistogramTracker { + track(value) { const bucket = Math.min(this._buckets.length - 1, Math.floor(value / this._bucketSize)); this._buckets[bucket].addValue(value); return this; } - saveAnalytics(): void { + saveAnalytics() { for (let i = 0; i < this._buckets.length; i++) { const bucket = this._buckets[i]; - if (bucket.getCount() > 0 && track != null) { - track(HISTOGRAM_TRACKER_KEY, { + if (bucket.getCount() > 0 && (_track || _load_track()).track != null) { + (0, (_track || _load_track()).track)(HISTOGRAM_TRACKER_KEY, { eventName: this._eventName, average: bucket.getAverage(), - samples: bucket.getCount(), + samples: bucket.getCount() }); } } this.clear(); } - clear(): void { + clear() { for (let i = 0; i < this._buckets.length; i++) { this._buckets[i].clear(); } } } +exports.HistogramTracker = HistogramTracker; \ No newline at end of file diff --git a/pkg/nuclide-analytics/lib/analytics.js b/pkg/nuclide-analytics/lib/analytics.js index e8cf6131c8..ede31f4a40 100644 --- a/pkg/nuclide-analytics/lib/analytics.js +++ b/pkg/nuclide-analytics/lib/analytics.js @@ -1,3 +1,9 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.track = track; /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,13 +11,8 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * */ // This is a stubbed implementation that other packages use to record analytics data & performance. -export function track( - eventName: string, - values?: {[key: string]: mixed}, - immediate?: boolean, -): ?Promise { -} +function track(eventName, values, immediate) {} \ No newline at end of file diff --git a/pkg/nuclide-analytics/lib/main.js b/pkg/nuclide-analytics/lib/main.js index cee7127a67..20dbd6865f 100644 --- a/pkg/nuclide-analytics/lib/main.js +++ b/pkg/nuclide-analytics/lib/main.js @@ -1,26 +1,54 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the license found in the LICENSE file in - * the root directory of this source tree. - * - * @flow - */ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.TimingTracker = exports.HistogramTracker = undefined; + +var _HistogramTracker; + +function _load_HistogramTracker() { + return _HistogramTracker = require('./HistogramTracker'); +} + +Object.defineProperty(exports, 'HistogramTracker', { + enumerable: true, + get: function () { + return (_HistogramTracker || _load_HistogramTracker()).HistogramTracker; + } +}); +exports.track = track; +exports.trackImmediate = trackImmediate; +exports.trackEvent = trackEvent; +exports.trackEvents = trackEvents; +exports.startTracking = startTracking; +exports.trackTiming = trackTiming; + +var _UniversalDisposable; + +function _load_UniversalDisposable() { + return _UniversalDisposable = _interopRequireDefault(require('../../commons-node/UniversalDisposable')); +} -import type {Observable} from 'rxjs'; +var _promise; -import UniversalDisposable from '../../commons-node/UniversalDisposable'; -import {isPromise} from '../../commons-node/promise'; -import performanceNow from '../../commons-node/performanceNow'; -import {track as rawTrack} from './track'; +function _load_promise() { + return _promise = require('../../commons-node/promise'); +} -export {HistogramTracker} from './HistogramTracker'; +var _performanceNow; + +function _load_performanceNow() { + return _performanceNow = _interopRequireDefault(require('../../commons-node/performanceNow')); +} -export type TrackingEvent = { - type: string, - data?: Object, -}; +var _track; + +function _load_track() { + return _track = require('./track'); +} + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /** * Track a set of values against a named event. @@ -29,66 +57,62 @@ export type TrackingEvent = { * @param eventName Name of the event to be tracked. * @param values The object containing the data to track. */ -export function track(eventName: string, values?: {[key: string]: mixed}): void { - rawTrack(eventName, values || {}); +function track(eventName, values) { + (0, (_track || _load_track()).track)(eventName, values || {}); } /** * Same as `track`, except this is guaranteed to send immediately. * The returned promise will resolve when the request completes (or reject on failure). */ -export function trackImmediate( - eventName: string, - values?: {[key: string]: mixed}, -): Promise { - return rawTrack(eventName, values || {}, true) || Promise.resolve(); +function trackImmediate(eventName, values) { + return (0, (_track || _load_track()).track)(eventName, values || {}, true) || Promise.resolve(); } /** * An alternative interface for `track` that accepts a single event object. This is particularly * useful when dealing with streams (Observables). */ -export function trackEvent(event: TrackingEvent): void { +function trackEvent(event) { track(event.type, event.data); } /** * Track each event in a stream of TrackingEvents. */ -export function trackEvents(events: Observable): IDisposable { - return new UniversalDisposable(events.subscribe(trackEvent)); +function trackEvents(events) { + return new (_UniversalDisposable || _load_UniversalDisposable()).default(events.subscribe(trackEvent)); } const PERFORMANCE_EVENT = 'performance'; -export class TimingTracker { - _eventName: string; - _startTime: number; +class TimingTracker { - constructor(eventName: string) { + constructor(eventName) { this._eventName = eventName; - this._startTime = performanceNow(); + this._startTime = (0, (_performanceNow || _load_performanceNow()).default)(); } - onError(error: Error): void { + onError(error) { this._trackTimingEvent(error); } - onSuccess(): void { - this._trackTimingEvent(/* error */ null); + onSuccess() { + this._trackTimingEvent( /* error */null); } - _trackTimingEvent(exception: ?Error): void { + _trackTimingEvent(exception) { track(PERFORMANCE_EVENT, { - duration: Math.round(performanceNow() - this._startTime).toString(), + duration: Math.round((0, (_performanceNow || _load_performanceNow()).default)() - this._startTime).toString(), eventName: this._eventName, error: exception ? '1' : '0', - exception: exception ? exception.toString() : '', + exception: exception ? exception.toString() : '' }); } } -export function startTracking(eventName: string): TimingTracker { +exports.TimingTracker = TimingTracker; +function startTracking(eventName) { return new TimingTracker(eventName); } @@ -101,18 +125,18 @@ export function startTracking(eventName: string): TimingTracker { * * Returns (or throws) the result of the operation. */ -export function trackTiming(eventName: string, operation: () => T): T { +function trackTiming(eventName, operation) { const tracker = startTracking(eventName); try { const result = operation(); - if (isPromise(result)) { + if ((0, (_promise || _load_promise()).isPromise)(result)) { // Atom uses a different Promise implementation than Nuclide, so the following is not true: // invariant(result instanceof Promise); // For the method returning a Promise, track the time after the promise is resolved/rejected. - return (result: any).then(value => { + return result.then(value => { tracker.onSuccess(); return value; }, reason => { @@ -127,4 +151,4 @@ export function trackTiming(eventName: string, operation: () => T): T { tracker.onError(error); throw error; } -} +} \ No newline at end of file diff --git a/pkg/nuclide-analytics/lib/track.js b/pkg/nuclide-analytics/lib/track.js index b56fda088a..08b948c3c1 100644 --- a/pkg/nuclide-analytics/lib/track.js +++ b/pkg/nuclide-analytics/lib/track.js @@ -1,17 +1,4 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the license found in the LICENSE file in - * the root directory of this source tree. - * - * @flow - */ - -export type TrackEvent = { - key: string, - values: {[key: string]: mixed}, -}; +'use strict'; // This extra module enables adding spies during testing. try { @@ -19,4 +6,12 @@ try { module.exports = require('../fb/analytics'); } catch (e) { module.exports = require('./analytics'); -} +} /** + * Copyright (c) 2015-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the license found in the LICENSE file in + * the root directory of this source tree. + * + * + */ \ No newline at end of file diff --git a/pkg/nuclide-analytics/spec/AnalyticsBatcher-spec.js b/pkg/nuclide-analytics/spec/AnalyticsBatcher-spec.js deleted file mode 100644 index c508bb7335..0000000000 --- a/pkg/nuclide-analytics/spec/AnalyticsBatcher-spec.js +++ /dev/null @@ -1,49 +0,0 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the license found in the LICENSE file in - * the root directory of this source tree. - * - * @flow - */ - -import {AnalyticsBatcher} from '../lib/AnalyticsBatcher'; - -describe('analytics - AnalyticsBatcher', () => { - it('batching track calls', () => { - const track = jasmine.createSpy('track'); - const batcher = new AnalyticsBatcher(track); - - batcher.track('key1', {}); - batcher.track('key2', {v1: 'value1'}); - expect(track).not.toHaveBeenCalled(); - - advanceClock(999); - expect(track).not.toHaveBeenCalled(); - advanceClock(1); - expect(track).toHaveBeenCalledWith([ - {key: 'key1', values: {}}, - {key: 'key2', values: {v1: 'value1'}}, - ]); - - batcher.track('key3', {}); - advanceClock(10000); - expect(track).toHaveBeenCalledWith([{key: 'key3', values: {}}]); - }); - - it('flush on dispose', () => { - const track = jasmine.createSpy('track'); - const batcher = new AnalyticsBatcher(track); - - batcher.track('key1', {}); - batcher.track('key2', {v1: 'value1'}); - expect(track).not.toHaveBeenCalled(); - - batcher.dispose(); - expect(track).toHaveBeenCalledWith([ - {key: 'key1', values: {}}, - {key: 'key2', values: {v1: 'value1'}}, - ]); - }); -}); diff --git a/pkg/nuclide-analytics/spec/HistogramTracker-spec.js b/pkg/nuclide-analytics/spec/HistogramTracker-spec.js deleted file mode 100644 index 77728ce199..0000000000 --- a/pkg/nuclide-analytics/spec/HistogramTracker-spec.js +++ /dev/null @@ -1,90 +0,0 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the license found in the LICENSE file in - * the root directory of this source tree. - * - * @flow - */ - -import {HistogramTracker} from '../lib/HistogramTracker'; - -describe('HistogramTracker', () => { - let trackSpy; - let tracker; - beforeEach(() => { - jasmine.useMockClock(); - const trackModule = require('../lib/track'); - trackSpy = spyOn(trackModule, 'track'); - tracker = new HistogramTracker('test', 100, 10, 5); - }); - - afterEach(() => { - tracker.dispose(); - }); - - it('can track some values', () => { - tracker.track(2); - tracker.track(3); - tracker.track(7); - tracker.track(9); - expect(tracker._buckets.length).toBe(10); - expect(tracker._buckets[0].getCount()).toBe(4); - expect(tracker._buckets[0].getAverage()).toBe(5.25); - - tracker.track(10); - tracker.track(10.5); - tracker.track(15.5); - expect(tracker._buckets[1].getCount()).toBe(3); - expect(tracker._buckets[1].getAverage()).toBe(12); - }); - - it('can save analytics', () => { - tracker.track(2); - tracker.track(15); - tracker.track(42); - tracker.saveAnalytics(); - - expect(trackSpy.calls.map(x => x.args)).toEqual([ - ['performance-histogram', {average: 2, samples: 1, eventName: 'test'}], - ['performance-histogram', {average: 15, samples: 1, eventName: 'test'}], - ['performance-histogram', {average: 42, samples: 1, eventName: 'test'}], - ]); - }); - - it('can be cleared', () => { - tracker.track(2); - tracker.clear(); - tracker.saveAnalytics(); - expect(trackSpy.calls.length).toBe(0); - }); - - it('can save analytics at an interval', () => { - tracker.track(2); - advanceClock(5 * 1000); - expect(trackSpy.callCount).toBe(1); - expect(trackSpy.calls[0].args).toEqual( - ['performance-histogram', {average: 2, samples: 1, eventName: 'test'}], - ); - - tracker.track(42); - advanceClock(5 * 1000); - expect(trackSpy.callCount).toBe(2); - expect(trackSpy.calls[1].args).toEqual( - ['performance-histogram', {average: 42, samples: 1, eventName: 'test'}], - ); - }); -}); - -describe('Histogram.dispose', () => { - it('stops after dispose', () => { - const trackModule = require('../lib/track'); - const trackSpy = spyOn(trackModule, 'track'); - const tracker = new HistogramTracker('test', 100, 10, 5); - tracker.track(1); - tracker.dispose(); - advanceClock(5 * 1000); - expect(trackSpy.callCount).toBe(0); - }); -}); diff --git a/pkg/nuclide-analytics/spec/track-spec.js b/pkg/nuclide-analytics/spec/track-spec.js deleted file mode 100644 index 540abefe3c..0000000000 --- a/pkg/nuclide-analytics/spec/track-spec.js +++ /dev/null @@ -1,84 +0,0 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the license found in the LICENSE file in - * the root directory of this source tree. - * - * @flow - */ - -import {startTracking, trackImmediate} from '..'; -import * as track from '../lib/track'; -import invariant from 'assert'; - -describe('startTracking', () => { - let trackKey; - let trackValues; - let startTime; - - beforeEach(() => { - spyOn(process, 'hrtime').andCallFake(() => { - if (startTime == null) { - startTime = Date.now(); - } - const milliseconds = Date.now() - startTime; - const seconds = Math.floor(milliseconds / 1000); - const nanoseconds = (milliseconds - seconds * 1000) * 1000000; - return [seconds, nanoseconds]; - }); - - // Clear intercepted tracking data. - trackKey = null; - trackValues = null; - - spyOn(track, 'track').andCallFake((key, values) => { - trackKey = key; - trackValues = values; - return Promise.resolve(); - }); - }); - - it('startTracking - success', () => { - const timer = startTracking('st-success'); - advanceClock(10); - timer.onSuccess(); - expect(track.track).toHaveBeenCalled(); - expect(trackKey).toBe('performance'); - invariant(trackValues != null); - expect(trackValues.duration).toBe('10'); - expect(trackValues.eventName).toBe('st-success'); - expect(trackValues.error).toBe('0'); - expect(trackValues.exception).toBe(''); - }); - - it('startTracking - error', () => { - const timer = startTracking('st-error'); - advanceClock(11); - timer.onError(new Error()); - expect(track.track).toHaveBeenCalled(); - expect(trackKey).toBe('performance'); - invariant(trackValues != null); - expect(trackValues.duration).toBe('11'); - expect(trackValues.eventName).toBe('st-error'); - expect(trackValues.error).toBe('1'); - expect(trackValues.exception).toBe('Error'); - }); -}); - -describe('trackImmediate', () => { - let spy; - beforeEach(() => { - spy = spyOn(track, 'track').andCallFake((key, values) => { - return Promise.resolve(1); - }); - }); - - it('should call track with immediate = true', () => { - waitsForPromise(async () => { - const result = await trackImmediate('test', {}); - expect(result).toBe(1); - expect(spy).toHaveBeenCalledWith('test', {}, true); - }); - }); -}); diff --git a/pkg/nuclide-arcanist-rpc/lib/ArcanistService.js b/pkg/nuclide-arcanist-rpc/lib/ArcanistService.js index 144d91199b..1c829ed388 100644 --- a/pkg/nuclide-arcanist-rpc/lib/ArcanistService.js +++ b/pkg/nuclide-arcanist-rpc/lib/ArcanistService.js @@ -1,190 +1,247 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the license found in the LICENSE file in - * the root directory of this source tree. - * - * @flow - */ - -import type {NuclideUri} from '../../commons-node/nuclideUri'; -import type {ConnectableObservable} from 'rxjs'; -import type {ProcessMessage} from '../../commons-node/process-rpc-types'; - -import {getEditMergeConfigs} from '../../nuclide-hg-rpc/lib/hg-utils'; -import invariant from 'assert'; -import {Observable} from 'rxjs'; -import nuclideUri from '../../commons-node/nuclideUri'; -import { - exitEventToMessage, - getOriginalEnvironment, - getOutputStream, - observeProcess, - safeSpawn, - scriptSafeSpawnAndObserveOutput, -} from '../../commons-node/process'; -import {niceSafeSpawn} from '../../commons-node/nice'; -import fsPromise from '../../commons-node/fsPromise'; -import { - fetchFilesChangedSinceRevision, -} from '../../nuclide-hg-rpc/lib/hg-revision-state-helpers'; -import { - expressionForRevisionsBeforeHead, -} from '../../nuclide-hg-rpc/lib/hg-revision-expression-helpers'; -import { - findHgRepository, -} from '../../nuclide-source-control-helpers'; -import {getLogger} from '../../nuclide-logging'; - -const ARC_CONFIG_FILE_NAME = '.arcconfig'; - -export type ArcDiagnostic = { - type: 'Error' | 'Warning', - text: string, - filePath: NuclideUri, - row: number, - col: number, - code: ?string, - - // For autofix - original?: string, - replacement?: string, -}; - -const arcConfigDirectoryMap: Map = new Map(); -const arcProjectMap: Map = new Map(); - -export async function findArcConfigDirectory(fileName: NuclideUri): Promise { - if (!arcConfigDirectoryMap.has(fileName)) { - const result = await fsPromise.findNearestFile(ARC_CONFIG_FILE_NAME, fileName); - arcConfigDirectoryMap.set(fileName, result); - } - return arcConfigDirectoryMap.get(fileName); -} +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.__TEST__ = exports.getProjectRelativePath = exports.findArcProjectIdAndDirectory = exports.findArcProjectIdOfPath = exports.readArcConfig = exports.findArcConfigDirectory = undefined; + +var _asyncToGenerator = _interopRequireDefault(require('async-to-generator')); + +let findArcConfigDirectory = exports.findArcConfigDirectory = (() => { + var _ref = (0, _asyncToGenerator.default)(function* (fileName) { + if (!arcConfigDirectoryMap.has(fileName)) { + const result = yield (_fsPromise || _load_fsPromise()).default.findNearestFile(ARC_CONFIG_FILE_NAME, fileName); + arcConfigDirectoryMap.set(fileName, result); + } + return arcConfigDirectoryMap.get(fileName); + }); + + return function findArcConfigDirectory(_x) { + return _ref.apply(this, arguments); + }; +})(); + +let readArcConfig = exports.readArcConfig = (() => { + var _ref2 = (0, _asyncToGenerator.default)(function* (fileName) { + const arcConfigDirectory = yield findArcConfigDirectory(fileName); + if (!arcConfigDirectory) { + return null; + } + if (!arcProjectMap.has(arcConfigDirectory)) { + const arcconfigFile = (_nuclideUri || _load_nuclideUri()).default.join(arcConfigDirectory, ARC_CONFIG_FILE_NAME); + const contents = yield (_fsPromise || _load_fsPromise()).default.readFile(arcconfigFile, 'utf8'); -export async function readArcConfig(fileName: NuclideUri): Promise { - const arcConfigDirectory = await findArcConfigDirectory(fileName); - if (!arcConfigDirectory) { + if (!(typeof contents === 'string')) { + throw new Error('Invariant violation: "typeof contents === \'string\'"'); + } + + const result = JSON.parse(contents); + arcProjectMap.set(arcConfigDirectory, result); + } + return arcProjectMap.get(arcConfigDirectory); + }); + + return function readArcConfig(_x2) { + return _ref2.apply(this, arguments); + }; +})(); + +let findArcProjectIdOfPath = exports.findArcProjectIdOfPath = (() => { + var _ref3 = (0, _asyncToGenerator.default)(function* (fileName) { + const project = yield readArcConfig(fileName); + return project ? project.project_id || project['project.name'] : null; + }); + + return function findArcProjectIdOfPath(_x3) { + return _ref3.apply(this, arguments); + }; +})(); + +let findArcProjectIdAndDirectory = exports.findArcProjectIdAndDirectory = (() => { + var _ref4 = (0, _asyncToGenerator.default)(function* (fileName) { + const directory = yield findArcConfigDirectory(fileName); + if (directory != null) { + // This will hit the directory map cache. + const projectId = yield findArcProjectIdOfPath(fileName); + if (projectId != null) { + return { projectId, directory }; + } + } return null; - } - if (!arcProjectMap.has(arcConfigDirectory)) { - const arcconfigFile = nuclideUri.join(arcConfigDirectory, ARC_CONFIG_FILE_NAME); - const contents = await fsPromise.readFile(arcconfigFile, 'utf8'); - invariant(typeof contents === 'string'); - const result = JSON.parse(contents); - arcProjectMap.set(arcConfigDirectory, result); - } - return arcProjectMap.get(arcConfigDirectory); + }); + + return function findArcProjectIdAndDirectory(_x4) { + return _ref4.apply(this, arguments); + }; +})(); + +let getProjectRelativePath = exports.getProjectRelativePath = (() => { + var _ref5 = (0, _asyncToGenerator.default)(function* (fileName) { + const arcPath = yield findArcConfigDirectory(fileName); + return arcPath && fileName ? (_nuclideUri || _load_nuclideUri()).default.relative(arcPath, fileName) : null; + }); + + return function getProjectRelativePath(_x5) { + return _ref5.apply(this, arguments); + }; +})(); + +let getMercurialHeadCommitChanges = (() => { + var _ref6 = (0, _asyncToGenerator.default)(function* (filePath) { + const hgRepoDetails = (0, (_nuclideSourceControlHelpers || _load_nuclideSourceControlHelpers()).findHgRepository)(filePath); + if (hgRepoDetails == null) { + throw new Error('Cannot find source control root to diff from'); + } + const filesChanged = yield (0, (_hgRevisionStateHelpers || _load_hgRevisionStateHelpers()).fetchFilesChangedSinceRevision)((0, (_hgRevisionExpressionHelpers || _load_hgRevisionExpressionHelpers()).expressionForRevisionsBeforeHead)(1), hgRepoDetails.workingDirectoryPath).refCount().toPromise(); + if (filesChanged == null) { + throw new Error('Failed to fetch commit changed files while diffing'); + } + return filesChanged; + }); + + return function getMercurialHeadCommitChanges(_x6) { + return _ref6.apply(this, arguments); + }; +})(); + +let getCommitBasedArcConfigDirectory = (() => { + var _ref7 = (0, _asyncToGenerator.default)(function* (filePath) { + // TODO Support other source control types file changes (e.g. `git`). + const filesChanged = yield getMercurialHeadCommitChanges(filePath); + let configLookupPath = null; + if (filesChanged.length > 0) { + configLookupPath = (_fsPromise || _load_fsPromise()).default.getCommonAncestorDirectory(filesChanged); + } else { + configLookupPath = filePath; + } + return findArcConfigDirectory(configLookupPath); + }); + + return function getCommitBasedArcConfigDirectory(_x7) { + return _ref7.apply(this, arguments); + }; +})(); + +let getArcExecOptions = (() => { + var _ref8 = (0, _asyncToGenerator.default)(function* (cwd, hgEditor) { + const options = { + cwd, + env: Object.assign({}, (yield (0, (_process || _load_process()).getOriginalEnvironment)()), { + ATOM_BACKUP_EDITOR: 'false' + }) + }; + + if (hgEditor != null) { + options.env.HGEDITOR = hgEditor; + } + + return options; + }); + + return function getArcExecOptions(_x8, _x9) { + return _ref8.apply(this, arguments); + }; +})(); + +exports.findDiagnostics = findDiagnostics; +exports.createPhabricatorRevision = createPhabricatorRevision; +exports.updatePhabricatorRevision = updatePhabricatorRevision; +exports.execArcPull = execArcPull; +exports.execArcLand = execArcLand; +exports.execArcPatch = execArcPatch; + +var _hgUtils; + +function _load_hgUtils() { + return _hgUtils = require('../../nuclide-hg-rpc/lib/hg-utils'); } -export async function findArcProjectIdOfPath(fileName: NuclideUri): Promise { - const project = await readArcConfig(fileName); - return project ? project.project_id || project['project.name'] : null; +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js'); + +var _nuclideUri; + +function _load_nuclideUri() { + return _nuclideUri = _interopRequireDefault(require('../../commons-node/nuclideUri')); } -export async function findArcProjectIdAndDirectory(fileName: NuclideUri): Promise { - const directory = await findArcConfigDirectory(fileName); - if (directory != null) { - // This will hit the directory map cache. - const projectId = await findArcProjectIdOfPath(fileName); - if (projectId != null) { - return {projectId, directory}; - } - } - return null; +var _process; + +function _load_process() { + return _process = require('../../commons-node/process'); } -export async function getProjectRelativePath(fileName: NuclideUri): Promise { - const arcPath = await findArcConfigDirectory(fileName); - return arcPath && fileName ? nuclideUri.relative(arcPath, fileName) : null; +var _nice; + +function _load_nice() { + return _nice = require('../../commons-node/nice'); } -export function findDiagnostics( - path: NuclideUri, - skip: Array, -): ConnectableObservable { - return Observable.fromPromise(findArcConfigDirectory(path)) - .switchMap(arcDir => { - if (arcDir == null) { - return Observable.empty(); - } - return execArcLint(arcDir, [path], skip); - }) - .publish(); +var _fsPromise; + +function _load_fsPromise() { + return _fsPromise = _interopRequireDefault(require('../../commons-node/fsPromise')); } -async function getMercurialHeadCommitChanges(filePath: string): Promise> { - const hgRepoDetails = findHgRepository(filePath); - if (hgRepoDetails == null) { - throw new Error('Cannot find source control root to diff from'); - } - const filesChanged = await fetchFilesChangedSinceRevision( - expressionForRevisionsBeforeHead(1), - hgRepoDetails.workingDirectoryPath, - ).refCount().toPromise(); - if (filesChanged == null) { - throw new Error('Failed to fetch commit changed files while diffing'); - } - return filesChanged; +var _hgRevisionStateHelpers; + +function _load_hgRevisionStateHelpers() { + return _hgRevisionStateHelpers = require('../../nuclide-hg-rpc/lib/hg-revision-state-helpers'); } -async function getCommitBasedArcConfigDirectory(filePath: string): Promise { - // TODO Support other source control types file changes (e.g. `git`). - const filesChanged = await getMercurialHeadCommitChanges(filePath); - let configLookupPath = null; - if (filesChanged.length > 0) { - configLookupPath = fsPromise.getCommonAncestorDirectory(filesChanged); - } else { - configLookupPath = filePath; - } - return findArcConfigDirectory(configLookupPath); +var _hgRevisionExpressionHelpers; + +function _load_hgRevisionExpressionHelpers() { + return _hgRevisionExpressionHelpers = require('../../nuclide-hg-rpc/lib/hg-revision-expression-helpers'); } +var _nuclideSourceControlHelpers; -async function getArcExecOptions( - cwd: string, - hgEditor?: string, -): Promise { - const options = { - cwd, - env: { - ...await getOriginalEnvironment(), - ATOM_BACKUP_EDITOR: 'false', - }, - }; +function _load_nuclideSourceControlHelpers() { + return _nuclideSourceControlHelpers = require('../../nuclide-source-control-helpers'); +} - if (hgEditor != null) { - options.env.HGEDITOR = hgEditor; - } +var _nuclideLogging; + +function _load_nuclideLogging() { + return _nuclideLogging = require('../../nuclide-logging'); +} - return options; +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const ARC_CONFIG_FILE_NAME = '.arcconfig'; /** + * Copyright (c) 2015-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the license found in the LICENSE file in + * the root directory of this source tree. + * + * + */ + +const arcConfigDirectoryMap = new Map(); +const arcProjectMap = new Map(); + +function findDiagnostics(path, skip) { + return _rxjsBundlesRxMinJs.Observable.fromPromise(findArcConfigDirectory(path)).switchMap(arcDir => { + if (arcDir == null) { + return _rxjsBundlesRxMinJs.Observable.empty(); + } + return execArcLint(arcDir, [path], skip); + }).publish(); } -function _callArcDiff( - filePath: NuclideUri, - extraArcDiffArgs: Array, -): Observable<{stderr?: string, stdout?: string}> { +function _callArcDiff(filePath, extraArcDiffArgs) { const args = ['diff', '--json'].concat(extraArcDiffArgs); - return Observable - .fromPromise(getCommitBasedArcConfigDirectory(filePath)) - .flatMap((arcConfigDir: ?string) => { - if (arcConfigDir == null) { - throw new Error('Failed to find Arcanist config. Is this project set up for Arcanist?'); - } - return Observable.fromPromise(getArcExecOptions(arcConfigDir)) - .switchMap(opts => scriptSafeSpawnAndObserveOutput('arc', args, opts)); - }).share(); + return _rxjsBundlesRxMinJs.Observable.fromPromise(getCommitBasedArcConfigDirectory(filePath)).flatMap(arcConfigDir => { + if (arcConfigDir == null) { + throw new Error('Failed to find Arcanist config. Is this project set up for Arcanist?'); + } + return _rxjsBundlesRxMinJs.Observable.fromPromise(getArcExecOptions(arcConfigDir)).switchMap(opts => (0, (_process || _load_process()).scriptSafeSpawnAndObserveOutput)('arc', args, opts)); + }).share(); } -function getArcDiffParams( - lintExcuse: ?string, - isPrepareMode?: boolean = false, -): Array { +function getArcDiffParams(lintExcuse, isPrepareMode = false) { const args = []; if (isPrepareMode) { args.push('--prepare'); @@ -197,27 +254,14 @@ function getArcDiffParams( return args; } -export function createPhabricatorRevision( - filePath: NuclideUri, - isPrepareMode: boolean, - lintExcuse: ?string, -): ConnectableObservable<{stderr?: string, stdout?: string}> { +function createPhabricatorRevision(filePath, isPrepareMode, lintExcuse) { const args = ['--verbatim', ...getArcDiffParams(lintExcuse, isPrepareMode)]; return _callArcDiff(filePath, args).publish(); } -export function updatePhabricatorRevision( - filePath: NuclideUri, - message: string, - allowUntracked: boolean, - lintExcuse: ?string, - verbatimModeEnabled: boolean, -): ConnectableObservable<{stderr?: string, stdout?: string}> { +function updatePhabricatorRevision(filePath, message, allowUntracked, lintExcuse, verbatimModeEnabled) { const baseArgs = ['-m', message, ...getArcDiffParams(lintExcuse)]; - const args = [ - ...(verbatimModeEnabled ? ['--verbatim'] : []), - ...baseArgs, - ]; + const args = [...(verbatimModeEnabled ? ['--verbatim'] : []), ...baseArgs]; if (allowUntracked) { args.push('--allow-untracked'); @@ -225,124 +269,91 @@ export function updatePhabricatorRevision( return _callArcDiff(filePath, args).publish(); } -export function execArcPull( - cwd: NuclideUri, - fetchLatest: boolean, - allowDirtyChanges: boolean, -): ConnectableObservable { - return Observable.fromPromise(getEditMergeConfigs()) - .switchMap(editMergeConfigs => { - const args = ['pull']; - if (fetchLatest) { - args.push('--latest'); - } +function execArcPull(cwd, fetchLatest, allowDirtyChanges) { + return _rxjsBundlesRxMinJs.Observable.fromPromise((0, (_hgUtils || _load_hgUtils()).getEditMergeConfigs)()).switchMap(editMergeConfigs => { + const args = ['pull']; + if (fetchLatest) { + args.push('--latest'); + } - if (allowDirtyChanges) { - args.push('--allow-dirty'); - } + if (allowDirtyChanges) { + args.push('--allow-dirty'); + } - return Observable.fromPromise(getArcExecOptions(cwd, editMergeConfigs.hgEditor)) - .switchMap(opts => observeProcess(() => safeSpawn('arc', args, opts))); - }).publish(); + return _rxjsBundlesRxMinJs.Observable.fromPromise(getArcExecOptions(cwd, editMergeConfigs.hgEditor)).switchMap(opts => (0, (_process || _load_process()).observeProcess)(() => (0, (_process || _load_process()).safeSpawn)('arc', args, opts))); + }).publish(); } -export function execArcLand( - cwd: NuclideUri, -): ConnectableObservable { +function execArcLand(cwd) { const args = ['land']; - return Observable.fromPromise(getArcExecOptions(cwd)) - .switchMap(opts => observeProcess(() => safeSpawn('arc', args, opts))) - .publish(); + return _rxjsBundlesRxMinJs.Observable.fromPromise(getArcExecOptions(cwd)).switchMap(opts => (0, (_process || _load_process()).observeProcess)(() => (0, (_process || _load_process()).safeSpawn)('arc', args, opts))).publish(); } -export function execArcPatch( - cwd: NuclideUri, - differentialRevision: string, -): ConnectableObservable { +function execArcPatch(cwd, differentialRevision) { const args = ['patch', differentialRevision]; - return Observable.fromPromise(getArcExecOptions(cwd)) - .switchMap(opts => observeProcess(() => safeSpawn('arc', args, opts))) - .publish(); + return _rxjsBundlesRxMinJs.Observable.fromPromise(getArcExecOptions(cwd)).switchMap(opts => (0, (_process || _load_process()).observeProcess)(() => (0, (_process || _load_process()).safeSpawn)('arc', args, opts))).publish(); } -function execArcLint( - cwd: string, - filePaths: Array, - skip: Array, -): Observable { - const args: Array = ['lint', '--output', 'json', ...filePaths]; +function execArcLint(cwd, filePaths, skip) { + const args = ['lint', '--output', 'json', ...filePaths]; if (skip.length > 0) { args.push('--skip', skip.join(',')); } - return Observable.fromPromise(getArcExecOptions(cwd)) - .switchMap(opts => niceSafeSpawn('arc', args, opts)) - .switchMap(arcProcess => getOutputStream(arcProcess, /* killTreeOnComplete */ true)) - .mergeMap(event => { - if (event.kind === 'error') { - return Observable.throw(event.error); - } else if (event.kind === 'exit') { - if (event.exitCode !== 0) { - return Observable.throw(Error(exitEventToMessage(event))); - } - return Observable.empty(); - } else if (event.kind === 'stderr') { - return Observable.empty(); + return _rxjsBundlesRxMinJs.Observable.fromPromise(getArcExecOptions(cwd)).switchMap(opts => (0, (_nice || _load_nice()).niceSafeSpawn)('arc', args, opts)).switchMap(arcProcess => (0, (_process || _load_process()).getOutputStream)(arcProcess, /* killTreeOnComplete */true)).mergeMap(event => { + if (event.kind === 'error') { + return _rxjsBundlesRxMinJs.Observable.throw(event.error); + } else if (event.kind === 'exit') { + if (event.exitCode !== 0) { + return _rxjsBundlesRxMinJs.Observable.throw(Error((0, (_process || _load_process()).exitEventToMessage)(event))); } - // Arc lint outputs multiple JSON objects on multiple lines. - const stdout = event.data.trim(); - if (stdout === '') { - return Observable.empty(); + return _rxjsBundlesRxMinJs.Observable.empty(); + } else if (event.kind === 'stderr') { + return _rxjsBundlesRxMinJs.Observable.empty(); + } + // Arc lint outputs multiple JSON objects on multiple lines. + const stdout = event.data.trim(); + if (stdout === '') { + return _rxjsBundlesRxMinJs.Observable.empty(); + } + let json; + try { + json = JSON.parse(stdout); + } catch (error) { + (0, (_nuclideLogging || _load_nuclideLogging()).getLogger)().warn('Error parsing `arc lint` JSON output', stdout); + return _rxjsBundlesRxMinJs.Observable.empty(); + } + const output = new Map(); + for (const file of Object.keys(json)) { + const errorsToAdd = json[file]; + let errors = output.get(file); + if (errors == null) { + errors = []; + output.set(file, errors); } - let json; - try { - json = JSON.parse(stdout); - } catch (error) { - getLogger().warn('Error parsing `arc lint` JSON output', stdout); - return Observable.empty(); - } - const output = new Map(); - for (const file of Object.keys(json)) { - const errorsToAdd = json[file]; - let errors = output.get(file); - if (errors == null) { - errors = []; - output.set(file, errors); - } - for (const error of errorsToAdd) { - errors.push(error); - } + for (const error of errorsToAdd) { + errors.push(error); } + } - const lints = []; - for (const file of filePaths) { - // TODO(7876450): For some reason, this does not work for particular - // values of pathToFile. Depending on the location of .arcconfig, we may - // get a key that is different from what `arc lint` actually returns, - // and end up without any lints for this path. - const key = nuclideUri.relative(cwd, file); - const rawLints = output.get(key); - if (rawLints) { - for (const lint of convertLints(file, rawLints)) { - lints.push(lint); - } + const lints = []; + for (const file of filePaths) { + // TODO(7876450): For some reason, this does not work for particular + // values of pathToFile. Depending on the location of .arcconfig, we may + // get a key that is different from what `arc lint` actually returns, + // and end up without any lints for this path. + const key = (_nuclideUri || _load_nuclideUri()).default.relative(cwd, file); + const rawLints = output.get(key); + if (rawLints) { + for (const lint of convertLints(file, rawLints)) { + lints.push(lint); } } - return Observable.from(lints); - }); + } + return _rxjsBundlesRxMinJs.Observable.from(lints); + }); } -function convertLints( - pathToFile: string, - lints: Array<{ - severity: string, - line: number, - char: number, - code: string, - description: string, - original?: string, - replacement?: string, - }>, -): Array { +function convertLints(pathToFile, lints) { return lints.map(lint => { // Choose an appropriate level based on lint['severity']. const severity = lint.severity; @@ -354,13 +365,13 @@ function convertLints( const col = Math.max(0, lint.char - 1); const row = Math.max(0, line - 1); - const diagnostic: ArcDiagnostic = { + const diagnostic = { type: level, text: lint.description, filePath: pathToFile, row, col, - code: lint.code, + code: lint.code }; if (lint.original != null) { diagnostic.original = lint.original; @@ -372,11 +383,11 @@ function convertLints( }); } -export const __TEST__ = { +const __TEST__ = exports.__TEST__ = { arcConfigDirectoryMap, arcProjectMap, reset() { arcConfigDirectoryMap.clear(); arcProjectMap.clear(); - }, -}; + } +}; \ No newline at end of file diff --git a/pkg/nuclide-arcanist-rpc/lib/ArcanistServiceProxy.js b/pkg/nuclide-arcanist-rpc/lib/ArcanistServiceProxy.js new file mode 100644 index 0000000000..a08b3a9e26 --- /dev/null +++ b/pkg/nuclide-arcanist-rpc/lib/ArcanistServiceProxy.js @@ -0,0 +1,1907 @@ +"use strict"; + +let Observable; + +module.exports = _client => { + const remoteModule = {}; + + remoteModule.findArcConfigDirectory = function (arg0) { + return _client.marshalArguments(Array.from(arguments), [{ + name: "fileName", + type: { + location: { + type: "source", + fileName: "ArcanistService.js", + line: 58 + }, + kind: "named", + name: "NuclideUri" + } + }]).then(args => { + return _client.callRemoteFunction("ArcanistService/findArcConfigDirectory", "promise", args); + }).then(value => { + return _client.unmarshal(value, { + location: { + type: "source", + fileName: "ArcanistService.js", + line: 58 + }, + kind: "nullable", + type: { + location: { + type: "source", + fileName: "ArcanistService.js", + line: 58 + }, + kind: "named", + name: "NuclideUri" + } + }); + }); + }; + + remoteModule.readArcConfig = function (arg0) { + return _client.marshalArguments(Array.from(arguments), [{ + name: "fileName", + type: { + location: { + type: "source", + fileName: "ArcanistService.js", + line: 66 + }, + kind: "named", + name: "NuclideUri" + } + }]).then(args => { + return _client.callRemoteFunction("ArcanistService/readArcConfig", "promise", args); + }).then(value => { + return _client.unmarshal(value, { + location: { + type: "source", + fileName: "ArcanistService.js", + line: 66 + }, + kind: "nullable", + type: { + location: { + type: "source", + fileName: "ArcanistService.js", + line: 66 + }, + kind: "any" + } + }); + }); + }; + + remoteModule.findArcProjectIdOfPath = function (arg0) { + return _client.marshalArguments(Array.from(arguments), [{ + name: "fileName", + type: { + location: { + type: "source", + fileName: "ArcanistService.js", + line: 81 + }, + kind: "named", + name: "NuclideUri" + } + }]).then(args => { + return _client.callRemoteFunction("ArcanistService/findArcProjectIdOfPath", "promise", args); + }).then(value => { + return _client.unmarshal(value, { + location: { + type: "source", + fileName: "ArcanistService.js", + line: 81 + }, + kind: "nullable", + type: { + location: { + type: "source", + fileName: "ArcanistService.js", + line: 81 + }, + kind: "string" + } + }); + }); + }; + + remoteModule.findArcProjectIdAndDirectory = function (arg0) { + return _client.marshalArguments(Array.from(arguments), [{ + name: "fileName", + type: { + location: { + type: "source", + fileName: "ArcanistService.js", + line: 86 + }, + kind: "named", + name: "NuclideUri" + } + }]).then(args => { + return _client.callRemoteFunction("ArcanistService/findArcProjectIdAndDirectory", "promise", args); + }).then(value => { + return _client.unmarshal(value, { + location: { + type: "source", + fileName: "ArcanistService.js", + line: 86 + }, + kind: "nullable", + type: { + location: { + type: "source", + fileName: "ArcanistService.js", + line: 86 + }, + kind: "object", + fields: [{ + location: { + type: "source", + fileName: "ArcanistService.js", + line: 87 + }, + name: "projectId", + type: { + location: { + type: "source", + fileName: "ArcanistService.js", + line: 87 + }, + kind: "string" + }, + optional: false + }, { + location: { + type: "source", + fileName: "ArcanistService.js", + line: 88 + }, + name: "directory", + type: { + location: { + type: "source", + fileName: "ArcanistService.js", + line: 88 + }, + kind: "named", + name: "NuclideUri" + }, + optional: false + }] + } + }); + }); + }; + + remoteModule.getProjectRelativePath = function (arg0) { + return _client.marshalArguments(Array.from(arguments), [{ + name: "fileName", + type: { + location: { + type: "source", + fileName: "ArcanistService.js", + line: 101 + }, + kind: "named", + name: "NuclideUri" + } + }]).then(args => { + return _client.callRemoteFunction("ArcanistService/getProjectRelativePath", "promise", args); + }).then(value => { + return _client.unmarshal(value, { + location: { + type: "source", + fileName: "ArcanistService.js", + line: 101 + }, + kind: "nullable", + type: { + location: { + type: "source", + fileName: "ArcanistService.js", + line: 101 + }, + kind: "string" + } + }); + }); + }; + + remoteModule.findDiagnostics = function (arg0, arg1) { + return Observable.fromPromise(_client.marshalArguments(Array.from(arguments), [{ + name: "path", + type: { + location: { + type: "source", + fileName: "ArcanistService.js", + line: 107 + }, + kind: "named", + name: "NuclideUri" + } + }, { + name: "skip", + type: { + location: { + type: "source", + fileName: "ArcanistService.js", + line: 108 + }, + kind: "array", + type: { + location: { + type: "source", + fileName: "ArcanistService.js", + line: 108 + }, + kind: "string" + } + } + }]).then(args => { + return _client.callRemoteFunction("ArcanistService/findDiagnostics", "observable", args); + })).concatMap(id => id).concatMap(value => { + return _client.unmarshal(value, { + location: { + type: "source", + fileName: "ArcanistService.js", + line: 109 + }, + kind: "named", + name: "ArcDiagnostic" + }); + }).publish(); + }; + + remoteModule.createPhabricatorRevision = function (arg0, arg1, arg2) { + return Observable.fromPromise(_client.marshalArguments(Array.from(arguments), [{ + name: "filePath", + type: { + location: { + type: "source", + fileName: "ArcanistService.js", + line: 201 + }, + kind: "named", + name: "NuclideUri" + } + }, { + name: "isPrepareMode", + type: { + location: { + type: "source", + fileName: "ArcanistService.js", + line: 202 + }, + kind: "boolean" + } + }, { + name: "lintExcuse", + type: { + location: { + type: "source", + fileName: "ArcanistService.js", + line: 203 + }, + kind: "nullable", + type: { + location: { + type: "source", + fileName: "ArcanistService.js", + line: 203 + }, + kind: "string" + } + } + }]).then(args => { + return _client.callRemoteFunction("ArcanistService/createPhabricatorRevision", "observable", args); + })).concatMap(id => id).concatMap(value => { + return _client.unmarshal(value, { + location: { + type: "source", + fileName: "ArcanistService.js", + line: 204 + }, + kind: "object", + fields: [{ + location: { + type: "source", + fileName: "ArcanistService.js", + line: 204 + }, + name: "stderr", + type: { + location: { + type: "source", + fileName: "ArcanistService.js", + line: 204 + }, + kind: "string" + }, + optional: true + }, { + location: { + type: "source", + fileName: "ArcanistService.js", + line: 204 + }, + name: "stdout", + type: { + location: { + type: "source", + fileName: "ArcanistService.js", + line: 204 + }, + kind: "string" + }, + optional: true + }] + }); + }).publish(); + }; + + remoteModule.updatePhabricatorRevision = function (arg0, arg1, arg2, arg3, arg4) { + return Observable.fromPromise(_client.marshalArguments(Array.from(arguments), [{ + name: "filePath", + type: { + location: { + type: "source", + fileName: "ArcanistService.js", + line: 210 + }, + kind: "named", + name: "NuclideUri" + } + }, { + name: "message", + type: { + location: { + type: "source", + fileName: "ArcanistService.js", + line: 211 + }, + kind: "string" + } + }, { + name: "allowUntracked", + type: { + location: { + type: "source", + fileName: "ArcanistService.js", + line: 212 + }, + kind: "boolean" + } + }, { + name: "lintExcuse", + type: { + location: { + type: "source", + fileName: "ArcanistService.js", + line: 213 + }, + kind: "nullable", + type: { + location: { + type: "source", + fileName: "ArcanistService.js", + line: 213 + }, + kind: "string" + } + } + }, { + name: "verbatimModeEnabled", + type: { + location: { + type: "source", + fileName: "ArcanistService.js", + line: 214 + }, + kind: "boolean" + } + }]).then(args => { + return _client.callRemoteFunction("ArcanistService/updatePhabricatorRevision", "observable", args); + })).concatMap(id => id).concatMap(value => { + return _client.unmarshal(value, { + location: { + type: "source", + fileName: "ArcanistService.js", + line: 215 + }, + kind: "object", + fields: [{ + location: { + type: "source", + fileName: "ArcanistService.js", + line: 215 + }, + name: "stderr", + type: { + location: { + type: "source", + fileName: "ArcanistService.js", + line: 215 + }, + kind: "string" + }, + optional: true + }, { + location: { + type: "source", + fileName: "ArcanistService.js", + line: 215 + }, + name: "stdout", + type: { + location: { + type: "source", + fileName: "ArcanistService.js", + line: 215 + }, + kind: "string" + }, + optional: true + }] + }); + }).publish(); + }; + + remoteModule.execArcPull = function (arg0, arg1, arg2) { + return Observable.fromPromise(_client.marshalArguments(Array.from(arguments), [{ + name: "cwd", + type: { + location: { + type: "source", + fileName: "ArcanistService.js", + line: 229 + }, + kind: "named", + name: "NuclideUri" + } + }, { + name: "fetchLatest", + type: { + location: { + type: "source", + fileName: "ArcanistService.js", + line: 230 + }, + kind: "boolean" + } + }, { + name: "allowDirtyChanges", + type: { + location: { + type: "source", + fileName: "ArcanistService.js", + line: 231 + }, + kind: "boolean" + } + }]).then(args => { + return _client.callRemoteFunction("ArcanistService/execArcPull", "observable", args); + })).concatMap(id => id).concatMap(value => { + return _client.unmarshal(value, { + location: { + type: "source", + fileName: "ArcanistService.js", + line: 232 + }, + kind: "named", + name: "ProcessMessage" + }); + }).publish(); + }; + + remoteModule.execArcLand = function (arg0) { + return Observable.fromPromise(_client.marshalArguments(Array.from(arguments), [{ + name: "cwd", + type: { + location: { + type: "source", + fileName: "ArcanistService.js", + line: 250 + }, + kind: "named", + name: "NuclideUri" + } + }]).then(args => { + return _client.callRemoteFunction("ArcanistService/execArcLand", "observable", args); + })).concatMap(id => id).concatMap(value => { + return _client.unmarshal(value, { + location: { + type: "source", + fileName: "ArcanistService.js", + line: 251 + }, + kind: "named", + name: "ProcessMessage" + }); + }).publish(); + }; + + remoteModule.execArcPatch = function (arg0, arg1) { + return Observable.fromPromise(_client.marshalArguments(Array.from(arguments), [{ + name: "cwd", + type: { + location: { + type: "source", + fileName: "ArcanistService.js", + line: 259 + }, + kind: "named", + name: "NuclideUri" + } + }, { + name: "differentialRevision", + type: { + location: { + type: "source", + fileName: "ArcanistService.js", + line: 260 + }, + kind: "string" + } + }]).then(args => { + return _client.callRemoteFunction("ArcanistService/execArcPatch", "observable", args); + })).concatMap(id => id).concatMap(value => { + return _client.unmarshal(value, { + location: { + type: "source", + fileName: "ArcanistService.js", + line: 261 + }, + kind: "named", + name: "ProcessMessage" + }); + }).publish(); + }; + + return remoteModule; +}; + +Object.defineProperty(module.exports, "inject", { + value: function () { + Observable = arguments[0]; + } +}); +Object.defineProperty(module.exports, "defs", { + value: new Map([["Object", { + kind: "alias", + name: "Object", + location: { + type: "builtin" + } + }], ["Date", { + kind: "alias", + name: "Date", + location: { + type: "builtin" + } + }], ["RegExp", { + kind: "alias", + name: "RegExp", + location: { + type: "builtin" + } + }], ["Buffer", { + kind: "alias", + name: "Buffer", + location: { + type: "builtin" + } + }], ["fs.Stats", { + kind: "alias", + name: "fs.Stats", + location: { + type: "builtin" + } + }], ["NuclideUri", { + kind: "alias", + name: "NuclideUri", + location: { + type: "builtin" + } + }], ["atom$Point", { + kind: "alias", + name: "atom$Point", + location: { + type: "builtin" + } + }], ["atom$Range", { + kind: "alias", + name: "atom$Range", + location: { + type: "builtin" + } + }], ["ArcDiagnostic", { + kind: "alias", + location: { + type: "source", + fileName: "ArcanistService.js", + line: 42 + }, + name: "ArcDiagnostic", + definition: { + location: { + type: "source", + fileName: "ArcanistService.js", + line: 42 + }, + kind: "object", + fields: [{ + location: { + type: "source", + fileName: "ArcanistService.js", + line: 43 + }, + name: "type", + type: { + location: { + type: "source", + fileName: "ArcanistService.js", + line: 43 + }, + kind: "union", + types: [{ + location: { + type: "source", + fileName: "ArcanistService.js", + line: 43 + }, + kind: "string-literal", + value: "Error" + }, { + location: { + type: "source", + fileName: "ArcanistService.js", + line: 43 + }, + kind: "string-literal", + value: "Warning" + }] + }, + optional: false + }, { + location: { + type: "source", + fileName: "ArcanistService.js", + line: 44 + }, + name: "text", + type: { + location: { + type: "source", + fileName: "ArcanistService.js", + line: 44 + }, + kind: "string" + }, + optional: false + }, { + location: { + type: "source", + fileName: "ArcanistService.js", + line: 45 + }, + name: "filePath", + type: { + location: { + type: "source", + fileName: "ArcanistService.js", + line: 45 + }, + kind: "named", + name: "NuclideUri" + }, + optional: false + }, { + location: { + type: "source", + fileName: "ArcanistService.js", + line: 46 + }, + name: "row", + type: { + location: { + type: "source", + fileName: "ArcanistService.js", + line: 46 + }, + kind: "number" + }, + optional: false + }, { + location: { + type: "source", + fileName: "ArcanistService.js", + line: 47 + }, + name: "col", + type: { + location: { + type: "source", + fileName: "ArcanistService.js", + line: 47 + }, + kind: "number" + }, + optional: false + }, { + location: { + type: "source", + fileName: "ArcanistService.js", + line: 48 + }, + name: "code", + type: { + location: { + type: "source", + fileName: "ArcanistService.js", + line: 48 + }, + kind: "nullable", + type: { + location: { + type: "source", + fileName: "ArcanistService.js", + line: 48 + }, + kind: "string" + } + }, + optional: false + }, { + location: { + type: "source", + fileName: "ArcanistService.js", + line: 51 + }, + name: "original", + type: { + location: { + type: "source", + fileName: "ArcanistService.js", + line: 51 + }, + kind: "string" + }, + optional: true + }, { + location: { + type: "source", + fileName: "ArcanistService.js", + line: 52 + }, + name: "replacement", + type: { + location: { + type: "source", + fileName: "ArcanistService.js", + line: 52 + }, + kind: "string" + }, + optional: true + }] + } + }], ["findArcConfigDirectory", { + kind: "function", + name: "findArcConfigDirectory", + location: { + type: "source", + fileName: "ArcanistService.js", + line: 58 + }, + type: { + location: { + type: "source", + fileName: "ArcanistService.js", + line: 58 + }, + kind: "function", + argumentTypes: [{ + name: "fileName", + type: { + location: { + type: "source", + fileName: "ArcanistService.js", + line: 58 + }, + kind: "named", + name: "NuclideUri" + } + }], + returnType: { + location: { + type: "source", + fileName: "ArcanistService.js", + line: 58 + }, + kind: "promise", + type: { + location: { + type: "source", + fileName: "ArcanistService.js", + line: 58 + }, + kind: "nullable", + type: { + location: { + type: "source", + fileName: "ArcanistService.js", + line: 58 + }, + kind: "named", + name: "NuclideUri" + } + } + } + } + }], ["readArcConfig", { + kind: "function", + name: "readArcConfig", + location: { + type: "source", + fileName: "ArcanistService.js", + line: 66 + }, + type: { + location: { + type: "source", + fileName: "ArcanistService.js", + line: 66 + }, + kind: "function", + argumentTypes: [{ + name: "fileName", + type: { + location: { + type: "source", + fileName: "ArcanistService.js", + line: 66 + }, + kind: "named", + name: "NuclideUri" + } + }], + returnType: { + location: { + type: "source", + fileName: "ArcanistService.js", + line: 66 + }, + kind: "promise", + type: { + location: { + type: "source", + fileName: "ArcanistService.js", + line: 66 + }, + kind: "nullable", + type: { + location: { + type: "source", + fileName: "ArcanistService.js", + line: 66 + }, + kind: "any" + } + } + } + } + }], ["findArcProjectIdOfPath", { + kind: "function", + name: "findArcProjectIdOfPath", + location: { + type: "source", + fileName: "ArcanistService.js", + line: 81 + }, + type: { + location: { + type: "source", + fileName: "ArcanistService.js", + line: 81 + }, + kind: "function", + argumentTypes: [{ + name: "fileName", + type: { + location: { + type: "source", + fileName: "ArcanistService.js", + line: 81 + }, + kind: "named", + name: "NuclideUri" + } + }], + returnType: { + location: { + type: "source", + fileName: "ArcanistService.js", + line: 81 + }, + kind: "promise", + type: { + location: { + type: "source", + fileName: "ArcanistService.js", + line: 81 + }, + kind: "nullable", + type: { + location: { + type: "source", + fileName: "ArcanistService.js", + line: 81 + }, + kind: "string" + } + } + } + } + }], ["findArcProjectIdAndDirectory", { + kind: "function", + name: "findArcProjectIdAndDirectory", + location: { + type: "source", + fileName: "ArcanistService.js", + line: 86 + }, + type: { + location: { + type: "source", + fileName: "ArcanistService.js", + line: 86 + }, + kind: "function", + argumentTypes: [{ + name: "fileName", + type: { + location: { + type: "source", + fileName: "ArcanistService.js", + line: 86 + }, + kind: "named", + name: "NuclideUri" + } + }], + returnType: { + location: { + type: "source", + fileName: "ArcanistService.js", + line: 86 + }, + kind: "promise", + type: { + location: { + type: "source", + fileName: "ArcanistService.js", + line: 86 + }, + kind: "nullable", + type: { + location: { + type: "source", + fileName: "ArcanistService.js", + line: 86 + }, + kind: "object", + fields: [{ + location: { + type: "source", + fileName: "ArcanistService.js", + line: 87 + }, + name: "projectId", + type: { + location: { + type: "source", + fileName: "ArcanistService.js", + line: 87 + }, + kind: "string" + }, + optional: false + }, { + location: { + type: "source", + fileName: "ArcanistService.js", + line: 88 + }, + name: "directory", + type: { + location: { + type: "source", + fileName: "ArcanistService.js", + line: 88 + }, + kind: "named", + name: "NuclideUri" + }, + optional: false + }] + } + } + } + } + }], ["getProjectRelativePath", { + kind: "function", + name: "getProjectRelativePath", + location: { + type: "source", + fileName: "ArcanistService.js", + line: 101 + }, + type: { + location: { + type: "source", + fileName: "ArcanistService.js", + line: 101 + }, + kind: "function", + argumentTypes: [{ + name: "fileName", + type: { + location: { + type: "source", + fileName: "ArcanistService.js", + line: 101 + }, + kind: "named", + name: "NuclideUri" + } + }], + returnType: { + location: { + type: "source", + fileName: "ArcanistService.js", + line: 101 + }, + kind: "promise", + type: { + location: { + type: "source", + fileName: "ArcanistService.js", + line: 101 + }, + kind: "nullable", + type: { + location: { + type: "source", + fileName: "ArcanistService.js", + line: 101 + }, + kind: "string" + } + } + } + } + }], ["findDiagnostics", { + kind: "function", + name: "findDiagnostics", + location: { + type: "source", + fileName: "ArcanistService.js", + line: 106 + }, + type: { + location: { + type: "source", + fileName: "ArcanistService.js", + line: 106 + }, + kind: "function", + argumentTypes: [{ + name: "path", + type: { + location: { + type: "source", + fileName: "ArcanistService.js", + line: 107 + }, + kind: "named", + name: "NuclideUri" + } + }, { + name: "skip", + type: { + location: { + type: "source", + fileName: "ArcanistService.js", + line: 108 + }, + kind: "array", + type: { + location: { + type: "source", + fileName: "ArcanistService.js", + line: 108 + }, + kind: "string" + } + } + }], + returnType: { + location: { + type: "source", + fileName: "ArcanistService.js", + line: 109 + }, + kind: "observable", + type: { + location: { + type: "source", + fileName: "ArcanistService.js", + line: 109 + }, + kind: "named", + name: "ArcDiagnostic" + } + } + } + }], ["createPhabricatorRevision", { + kind: "function", + name: "createPhabricatorRevision", + location: { + type: "source", + fileName: "ArcanistService.js", + line: 200 + }, + type: { + location: { + type: "source", + fileName: "ArcanistService.js", + line: 200 + }, + kind: "function", + argumentTypes: [{ + name: "filePath", + type: { + location: { + type: "source", + fileName: "ArcanistService.js", + line: 201 + }, + kind: "named", + name: "NuclideUri" + } + }, { + name: "isPrepareMode", + type: { + location: { + type: "source", + fileName: "ArcanistService.js", + line: 202 + }, + kind: "boolean" + } + }, { + name: "lintExcuse", + type: { + location: { + type: "source", + fileName: "ArcanistService.js", + line: 203 + }, + kind: "nullable", + type: { + location: { + type: "source", + fileName: "ArcanistService.js", + line: 203 + }, + kind: "string" + } + } + }], + returnType: { + location: { + type: "source", + fileName: "ArcanistService.js", + line: 204 + }, + kind: "observable", + type: { + location: { + type: "source", + fileName: "ArcanistService.js", + line: 204 + }, + kind: "object", + fields: [{ + location: { + type: "source", + fileName: "ArcanistService.js", + line: 204 + }, + name: "stderr", + type: { + location: { + type: "source", + fileName: "ArcanistService.js", + line: 204 + }, + kind: "string" + }, + optional: true + }, { + location: { + type: "source", + fileName: "ArcanistService.js", + line: 204 + }, + name: "stdout", + type: { + location: { + type: "source", + fileName: "ArcanistService.js", + line: 204 + }, + kind: "string" + }, + optional: true + }] + } + } + } + }], ["updatePhabricatorRevision", { + kind: "function", + name: "updatePhabricatorRevision", + location: { + type: "source", + fileName: "ArcanistService.js", + line: 209 + }, + type: { + location: { + type: "source", + fileName: "ArcanistService.js", + line: 209 + }, + kind: "function", + argumentTypes: [{ + name: "filePath", + type: { + location: { + type: "source", + fileName: "ArcanistService.js", + line: 210 + }, + kind: "named", + name: "NuclideUri" + } + }, { + name: "message", + type: { + location: { + type: "source", + fileName: "ArcanistService.js", + line: 211 + }, + kind: "string" + } + }, { + name: "allowUntracked", + type: { + location: { + type: "source", + fileName: "ArcanistService.js", + line: 212 + }, + kind: "boolean" + } + }, { + name: "lintExcuse", + type: { + location: { + type: "source", + fileName: "ArcanistService.js", + line: 213 + }, + kind: "nullable", + type: { + location: { + type: "source", + fileName: "ArcanistService.js", + line: 213 + }, + kind: "string" + } + } + }, { + name: "verbatimModeEnabled", + type: { + location: { + type: "source", + fileName: "ArcanistService.js", + line: 214 + }, + kind: "boolean" + } + }], + returnType: { + location: { + type: "source", + fileName: "ArcanistService.js", + line: 215 + }, + kind: "observable", + type: { + location: { + type: "source", + fileName: "ArcanistService.js", + line: 215 + }, + kind: "object", + fields: [{ + location: { + type: "source", + fileName: "ArcanistService.js", + line: 215 + }, + name: "stderr", + type: { + location: { + type: "source", + fileName: "ArcanistService.js", + line: 215 + }, + kind: "string" + }, + optional: true + }, { + location: { + type: "source", + fileName: "ArcanistService.js", + line: 215 + }, + name: "stdout", + type: { + location: { + type: "source", + fileName: "ArcanistService.js", + line: 215 + }, + kind: "string" + }, + optional: true + }] + } + } + } + }], ["execArcPull", { + kind: "function", + name: "execArcPull", + location: { + type: "source", + fileName: "ArcanistService.js", + line: 228 + }, + type: { + location: { + type: "source", + fileName: "ArcanistService.js", + line: 228 + }, + kind: "function", + argumentTypes: [{ + name: "cwd", + type: { + location: { + type: "source", + fileName: "ArcanistService.js", + line: 229 + }, + kind: "named", + name: "NuclideUri" + } + }, { + name: "fetchLatest", + type: { + location: { + type: "source", + fileName: "ArcanistService.js", + line: 230 + }, + kind: "boolean" + } + }, { + name: "allowDirtyChanges", + type: { + location: { + type: "source", + fileName: "ArcanistService.js", + line: 231 + }, + kind: "boolean" + } + }], + returnType: { + location: { + type: "source", + fileName: "ArcanistService.js", + line: 232 + }, + kind: "observable", + type: { + location: { + type: "source", + fileName: "ArcanistService.js", + line: 232 + }, + kind: "named", + name: "ProcessMessage" + } + } + } + }], ["execArcLand", { + kind: "function", + name: "execArcLand", + location: { + type: "source", + fileName: "ArcanistService.js", + line: 249 + }, + type: { + location: { + type: "source", + fileName: "ArcanistService.js", + line: 249 + }, + kind: "function", + argumentTypes: [{ + name: "cwd", + type: { + location: { + type: "source", + fileName: "ArcanistService.js", + line: 250 + }, + kind: "named", + name: "NuclideUri" + } + }], + returnType: { + location: { + type: "source", + fileName: "ArcanistService.js", + line: 251 + }, + kind: "observable", + type: { + location: { + type: "source", + fileName: "ArcanistService.js", + line: 251 + }, + kind: "named", + name: "ProcessMessage" + } + } + } + }], ["execArcPatch", { + kind: "function", + name: "execArcPatch", + location: { + type: "source", + fileName: "ArcanistService.js", + line: 258 + }, + type: { + location: { + type: "source", + fileName: "ArcanistService.js", + line: 258 + }, + kind: "function", + argumentTypes: [{ + name: "cwd", + type: { + location: { + type: "source", + fileName: "ArcanistService.js", + line: 259 + }, + kind: "named", + name: "NuclideUri" + } + }, { + name: "differentialRevision", + type: { + location: { + type: "source", + fileName: "ArcanistService.js", + line: 260 + }, + kind: "string" + } + }], + returnType: { + location: { + type: "source", + fileName: "ArcanistService.js", + line: 261 + }, + kind: "observable", + type: { + location: { + type: "source", + fileName: "ArcanistService.js", + line: 261 + }, + kind: "named", + name: "ProcessMessage" + } + } + } + }], ["ProcessExitMessage", { + kind: "alias", + location: { + type: "source", + fileName: "process-rpc-types.js", + line: 13 + }, + name: "ProcessExitMessage", + definition: { + location: { + type: "source", + fileName: "process-rpc-types.js", + line: 13 + }, + kind: "object", + fields: [{ + location: { + type: "source", + fileName: "process-rpc-types.js", + line: 14 + }, + name: "kind", + type: { + location: { + type: "source", + fileName: "process-rpc-types.js", + line: 14 + }, + kind: "string-literal", + value: "exit" + }, + optional: false + }, { + location: { + type: "source", + fileName: "process-rpc-types.js", + line: 15 + }, + name: "exitCode", + type: { + location: { + type: "source", + fileName: "process-rpc-types.js", + line: 15 + }, + kind: "nullable", + type: { + location: { + type: "source", + fileName: "process-rpc-types.js", + line: 15 + }, + kind: "number" + } + }, + optional: false + }, { + location: { + type: "source", + fileName: "process-rpc-types.js", + line: 16 + }, + name: "signal", + type: { + location: { + type: "source", + fileName: "process-rpc-types.js", + line: 16 + }, + kind: "nullable", + type: { + location: { + type: "source", + fileName: "process-rpc-types.js", + line: 16 + }, + kind: "string" + } + }, + optional: false + }] + } + }], ["ProcessMessage", { + kind: "alias", + location: { + type: "source", + fileName: "process-rpc-types.js", + line: 20 + }, + name: "ProcessMessage", + definition: { + location: { + type: "source", + fileName: "process-rpc-types.js", + line: 20 + }, + kind: "union", + types: [{ + location: { + type: "source", + fileName: "process-rpc-types.js", + line: 20 + }, + kind: "object", + fields: [{ + location: { + type: "source", + fileName: "process-rpc-types.js", + line: 21 + }, + name: "kind", + type: { + location: { + type: "source", + fileName: "process-rpc-types.js", + line: 21 + }, + kind: "string-literal", + value: "stdout" + }, + optional: false + }, { + location: { + type: "source", + fileName: "process-rpc-types.js", + line: 22 + }, + name: "data", + type: { + location: { + type: "source", + fileName: "process-rpc-types.js", + line: 22 + }, + kind: "string" + }, + optional: false + }] + }, { + location: { + type: "source", + fileName: "process-rpc-types.js", + line: 23 + }, + kind: "object", + fields: [{ + location: { + type: "source", + fileName: "process-rpc-types.js", + line: 24 + }, + name: "kind", + type: { + location: { + type: "source", + fileName: "process-rpc-types.js", + line: 24 + }, + kind: "string-literal", + value: "stderr" + }, + optional: false + }, { + location: { + type: "source", + fileName: "process-rpc-types.js", + line: 25 + }, + name: "data", + type: { + location: { + type: "source", + fileName: "process-rpc-types.js", + line: 25 + }, + kind: "string" + }, + optional: false + }] + }, { + location: { + type: "source", + fileName: "process-rpc-types.js", + line: 13 + }, + kind: "object", + fields: [{ + location: { + type: "source", + fileName: "process-rpc-types.js", + line: 14 + }, + name: "kind", + type: { + location: { + type: "source", + fileName: "process-rpc-types.js", + line: 14 + }, + kind: "string-literal", + value: "exit" + }, + optional: false + }, { + location: { + type: "source", + fileName: "process-rpc-types.js", + line: 15 + }, + name: "exitCode", + type: { + location: { + type: "source", + fileName: "process-rpc-types.js", + line: 15 + }, + kind: "nullable", + type: { + location: { + type: "source", + fileName: "process-rpc-types.js", + line: 15 + }, + kind: "number" + } + }, + optional: false + }, { + location: { + type: "source", + fileName: "process-rpc-types.js", + line: 16 + }, + name: "signal", + type: { + location: { + type: "source", + fileName: "process-rpc-types.js", + line: 16 + }, + kind: "nullable", + type: { + location: { + type: "source", + fileName: "process-rpc-types.js", + line: 16 + }, + kind: "string" + } + }, + optional: false + }] + }, { + location: { + type: "source", + fileName: "process-rpc-types.js", + line: 26 + }, + kind: "object", + fields: [{ + location: { + type: "source", + fileName: "process-rpc-types.js", + line: 27 + }, + name: "kind", + type: { + location: { + type: "source", + fileName: "process-rpc-types.js", + line: 27 + }, + kind: "string-literal", + value: "error" + }, + optional: false + }, { + location: { + type: "source", + fileName: "process-rpc-types.js", + line: 28 + }, + name: "error", + type: { + location: { + type: "source", + fileName: "process-rpc-types.js", + line: 28 + }, + kind: "named", + name: "Object" + }, + optional: false + }] + }], + discriminantField: "kind" + } + }], ["ProcessInfo", { + kind: "alias", + location: { + type: "source", + fileName: "process-rpc-types.js", + line: 31 + }, + name: "ProcessInfo", + definition: { + location: { + type: "source", + fileName: "process-rpc-types.js", + line: 31 + }, + kind: "object", + fields: [{ + location: { + type: "source", + fileName: "process-rpc-types.js", + line: 32 + }, + name: "parentPid", + type: { + location: { + type: "source", + fileName: "process-rpc-types.js", + line: 32 + }, + kind: "number" + }, + optional: false + }, { + location: { + type: "source", + fileName: "process-rpc-types.js", + line: 33 + }, + name: "pid", + type: { + location: { + type: "source", + fileName: "process-rpc-types.js", + line: 33 + }, + kind: "number" + }, + optional: false + }, { + location: { + type: "source", + fileName: "process-rpc-types.js", + line: 34 + }, + name: "command", + type: { + location: { + type: "source", + fileName: "process-rpc-types.js", + line: 34 + }, + kind: "string" + }, + optional: false + }] + } + }]]) +}); \ No newline at end of file diff --git a/pkg/nuclide-arcanist-rpc/lib/utils.js b/pkg/nuclide-arcanist-rpc/lib/utils.js index 12c0922bae..9407fc30a8 100644 --- a/pkg/nuclide-arcanist-rpc/lib/utils.js +++ b/pkg/nuclide-arcanist-rpc/lib/utils.js @@ -1,26 +1,27 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the license found in the LICENSE file in - * the root directory of this source tree. - * - * @flow - */ - -export type PhabricatorRevisionInfo = { - url: string, - id: number, - name: string, -}; - -const DIFFERENTIAL_REVISION_REGEX = /^Differential Revision:\s*(\S+)/im; +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.getPhabricatorRevisionFromCommitMessage = getPhabricatorRevisionFromCommitMessage; +exports.getPhabricatorRevisionFromUrl = getPhabricatorRevisionFromUrl; +exports.getCommitAuthorFromAuthorEmail = getCommitAuthorFromAuthorEmail; + + +const DIFFERENTIAL_REVISION_REGEX = /^Differential Revision:\s*(\S+)/im; /** + * Copyright (c) 2015-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the license found in the LICENSE file in + * the root directory of this source tree. + * + * + */ + const DIFFERENTIAL_ID_REGEX = /[dD]([1-9][0-9]{5,})/im; const COMMIT_AUTHOR_REGEX = /.*<(.*)@.*>/im; -export function getPhabricatorRevisionFromCommitMessage( - commitMessage: string, -): ?PhabricatorRevisionInfo { +function getPhabricatorRevisionFromCommitMessage(commitMessage) { const match = DIFFERENTIAL_REVISION_REGEX.exec(commitMessage); if (match === null) { return null; @@ -29,9 +30,7 @@ export function getPhabricatorRevisionFromCommitMessage( return getPhabricatorRevisionFromUrl(match[1]); } -export function getPhabricatorRevisionFromUrl( - diffUrl: string, -): ?PhabricatorRevisionInfo { +function getPhabricatorRevisionFromUrl(diffUrl) { const match = DIFFERENTIAL_ID_REGEX.exec(diffUrl); if (match === null) { return null; @@ -40,17 +39,15 @@ export function getPhabricatorRevisionFromUrl( return { url: diffUrl, id: parseInt(match[1], 10), - name: `D${match[1]}`, + name: `D${match[1]}` }; } -export function getCommitAuthorFromAuthorEmail( - author: string, -): ?string { +function getCommitAuthorFromAuthorEmail(author) { const match = COMMIT_AUTHOR_REGEX.exec(author); if (match === null) { return null; } else { return match[1]; } -} +} \ No newline at end of file diff --git a/pkg/nuclide-arcanist-rpc/spec/arcanist-base-spec.js b/pkg/nuclide-arcanist-rpc/spec/arcanist-base-spec.js deleted file mode 100644 index 391bbcaca1..0000000000 --- a/pkg/nuclide-arcanist-rpc/spec/arcanist-base-spec.js +++ /dev/null @@ -1,196 +0,0 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the license found in the LICENSE file in - * the root directory of this source tree. - * - * @flow - */ - -import * as arcanist from '..'; -import nuclideUri from '../../commons-node/nuclideUri'; -import fsPromise from '../../commons-node/fsPromise'; -import {copyFixture} from '../../nuclide-test-helpers'; - -const rootConfig = { - project_id: 'project1', -}; -const nestedConfig = { - project_id: 'project-nested', -}; - -describe('nuclide-arcanist-rpc', () => { - let rootPath: string = (null: any); - let rootParentPath: string = (null: any); - let dirPath: string = (null: any); - let file1Path: string = (null: any); - let file2Path: string = (null: any); - let nestedPath: string = (null: any); - - beforeEach(() => { - waitsForPromise(async () => { - rootPath = await copyFixture('arc', __dirname); - rootParentPath = nuclideUri.dirname(rootPath); - dirPath = nuclideUri.join(rootPath, 'dir1'); - file1Path = nuclideUri.join(dirPath, 'file1'); - file2Path = nuclideUri.join(rootPath, 'file2'); - nestedPath = nuclideUri.join(rootPath, 'nested-project'); - - await Promise.all([ - fsPromise.rename( - nuclideUri.join(rootPath, '.arcconfig.test'), - nuclideUri.join(rootPath, '.arcconfig'), - ), - fsPromise.rename( - nuclideUri.join(nestedPath, '.arcconfig.test'), - nuclideUri.join(nestedPath, '.arcconfig'), - ), - ]); - }); - }); - - it('findArcConfigDirectory', () => { - waitsForPromise(async () => { - expect(await arcanist.findArcConfigDirectory(rootPath)).toBe(rootPath); - expect(await arcanist.findArcConfigDirectory(dirPath)).toBe(rootPath); - expect(await arcanist.findArcConfigDirectory(file1Path)).toBe(rootPath); - expect(await arcanist.findArcConfigDirectory(file2Path)).toBe(rootPath); - expect(await arcanist.findArcConfigDirectory(nestedPath)).toBe(nestedPath); - expect(await arcanist.findArcConfigDirectory(rootParentPath)).toBe(null); - }); - }); - - it('readArcConfig', () => { - waitsForPromise(async () => { - expect(await arcanist.readArcConfig(rootPath)).toEqual(rootConfig); - expect(await arcanist.readArcConfig(dirPath)).toEqual(rootConfig); - expect(await arcanist.readArcConfig(file1Path)).toEqual(rootConfig); - expect(await arcanist.readArcConfig(file2Path)).toEqual(rootConfig); - expect(await arcanist.readArcConfig(nestedPath)).toEqual(nestedConfig); - expect(await arcanist.readArcConfig(rootParentPath)).toEqual(null); - }); - }); - - it('findArcProjectIdOfPath', () => { - waitsForPromise(async () => { - expect(await arcanist.findArcProjectIdOfPath(rootPath)).toBe('project1'); - expect(await arcanist.findArcProjectIdOfPath(dirPath)).toBe('project1'); - expect(await arcanist.findArcProjectIdOfPath(file1Path)).toBe('project1'); - expect(await arcanist.findArcProjectIdOfPath(file2Path)).toBe('project1'); - expect(await arcanist.findArcProjectIdOfPath(nestedPath)).toBe('project-nested'); - expect(await arcanist.findArcProjectIdOfPath(rootParentPath)).toBe(null); - }); - }); - - it('getProjectRelativePath', () => { - waitsForPromise(async () => { - expect(await arcanist.getProjectRelativePath(rootPath)).toBe(''); - expect(await arcanist.getProjectRelativePath(dirPath)).toBe('dir1'); - expect(await arcanist.getProjectRelativePath(file1Path)).toBe('dir1/file1'); - expect(await arcanist.getProjectRelativePath(file2Path)).toBe('file2'); - expect(await arcanist.getProjectRelativePath(nestedPath)).toBe(''); - expect(await arcanist.getProjectRelativePath(rootParentPath)).toBe(null); - }); - }); - - describe('findDiagnostics', () => { - // Map from fake arc config dir to fake files within it. - const filePathMap: Map> = new Map([ - ['/fake/path/one', [ - 'path1', - 'path2', - '/fake/path/one/path1', - ]], - ['/fake/path/two', [ - 'foo', - 'bar', - ]], - ]); - let arcResult: any; - let execArgs: any; - const fakeLint = { - description: 'Trailing spaces not allowed. (no-trailing-spaces)', - severity: 'warning', - original: ' ', - line: 78, - bypassChangedLineFiltering: null, - name: 'ESLint reported a warning.', - granularity: 1, - locations: [], - replacement: '', - code: 'FBNUCLIDELINT1', - char: 2, - context: 'this usually contains some nearby code', - }; - const fakeLintResult = { - type: 'Warning', - text: 'Trailing spaces not allowed. (no-trailing-spaces)', - filePath: '/fake/path/one/path1', - row: 77, - col: 1, - code: 'FBNUCLIDELINT1', - original: ' ', - replacement: '', - }; - - function setResult(...results) { - // This mimics the output that `arc lint` can provide. Sometimes it provides results as valid - // JSON objects separated by a newline. The result is not valid JSON but it's what we get. - arcResult = results.map(result => JSON.stringify(result)); - } - - beforeEach(() => { - setResult({}); - execArgs = []; - spyOn(require('../../commons-node/nice'), 'niceSafeSpawn') - .andCallFake(async (command, args, options) => { - execArgs.push(args); - }); - spyOn(require('../../commons-node/process'), 'getOutputStream') - .andCallFake(() => { - return arcResult.map(line => ({kind: 'stdout', data: line})); - }); - arcanist.__TEST__.reset(); - // Add these paths to the arcConfigDirectoryMap as a roundabout way to mock - // findArcConfigDirectory. - for (const [arcDir, filePaths] of filePathMap) { - for (const filePath of filePaths) { - arcanist.__TEST__.arcConfigDirectoryMap.set(filePath, arcDir); - } - } - }); - - it('should call `arc lint` with the paths', () => { - waitsForPromise(async () => { - const filePath = 'path1'; - await arcanist.findDiagnostics(filePath, []) - .refCount().toPromise(); - // Expect arc lint to be called once - expect(execArgs.length).toBe(1); - expect(execArgs[0].indexOf(filePath)).toBeGreaterThan(-1); - }); - }); - - it('should return the lints', () => { - waitsForPromise(async () => { - setResult({ - path1: [fakeLint], - }); - const lints = await arcanist.findDiagnostics('/fake/path/one/path1', []) - .refCount().toArray().toPromise(); - expect(lints).toEqual([fakeLintResult]); - }); - }); - - it('should return the lints even when they are in separate JSON objects', () => { - waitsForPromise(async () => { - const fakeArcResult = {path1: [fakeLint]}; - setResult(fakeArcResult, fakeArcResult); - const lints = await arcanist.findDiagnostics('/fake/path/one/path1', []) - .refCount().toArray().toPromise(); - expect(lints).toEqual([fakeLintResult, fakeLintResult]); - }); - }); - }); -}); diff --git a/pkg/nuclide-arcanist-rpc/spec/fixtures/arc/.arcconfig.test b/pkg/nuclide-arcanist-rpc/spec/fixtures/arc/.arcconfig.test deleted file mode 100644 index 3c9c94383d..0000000000 --- a/pkg/nuclide-arcanist-rpc/spec/fixtures/arc/.arcconfig.test +++ /dev/null @@ -1,3 +0,0 @@ -{ - "project_id": "project1" -} diff --git a/pkg/nuclide-arcanist-rpc/spec/fixtures/arc/dir1/file1 b/pkg/nuclide-arcanist-rpc/spec/fixtures/arc/dir1/file1 deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/pkg/nuclide-arcanist-rpc/spec/fixtures/arc/file2 b/pkg/nuclide-arcanist-rpc/spec/fixtures/arc/file2 deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/pkg/nuclide-arcanist-rpc/spec/fixtures/arc/nested-project/.arcconfig.test b/pkg/nuclide-arcanist-rpc/spec/fixtures/arc/nested-project/.arcconfig.test deleted file mode 100644 index 55afbe6548..0000000000 --- a/pkg/nuclide-arcanist-rpc/spec/fixtures/arc/nested-project/.arcconfig.test +++ /dev/null @@ -1,3 +0,0 @@ -{ - "project_id": "project-nested" -} diff --git a/pkg/nuclide-arcanist-rpc/spec/utils-spec.js b/pkg/nuclide-arcanist-rpc/spec/utils-spec.js deleted file mode 100644 index 9890c9ac9a..0000000000 --- a/pkg/nuclide-arcanist-rpc/spec/utils-spec.js +++ /dev/null @@ -1,46 +0,0 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the license found in the LICENSE file in - * the root directory of this source tree. - * - * @flow - */ - -import invariant from 'assert'; - -import {getPhabricatorRevisionFromCommitMessage} from '../lib/utils'; - -describe('utils', () => { - const testCases = [ - [ - 'Differential Revision: https://phabricator.intern.facebook.com/D169775', - {id: 169775, name: 'D169775', url: 'https://phabricator.intern.facebook.com/D169775'}, - ], - ['Some stuff', null], - [ - (`Multiline - - message - Differential Revision: https://phabricator.intern.facebook.com/d123456 - Test plan: foo!`).replace(/^ +/gm, ''), - {id: 123456, name: 'D123456', url: 'https://phabricator.intern.facebook.com/d123456'}, - ], - ]; - it('can parse a commit message and get the revision ID', () => { - for (const [message, correctAnswer] of testCases) { - const msg = `Test data: '${message}'`; - const revisionInfo = getPhabricatorRevisionFromCommitMessage(message); - if (correctAnswer == null) { - expect(revisionInfo).toBeNull(msg); - } else { - expect(revisionInfo).not.toBeNull(msg); - invariant(revisionInfo != null); - expect(revisionInfo.id).toBe(correctAnswer.id, msg); - expect(revisionInfo.name).toBe(correctAnswer.name, msg); - expect(revisionInfo.url).toBe(correctAnswer.url, msg); - } - } - }); -}); diff --git a/pkg/nuclide-arcanist/lib/ArcBuildSystem.js b/pkg/nuclide-arcanist/lib/ArcBuildSystem.js index 067b188db2..65a7960c88 100644 --- a/pkg/nuclide-arcanist/lib/ArcBuildSystem.js +++ b/pkg/nuclide-arcanist/lib/ArcBuildSystem.js @@ -1,67 +1,63 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the license found in the LICENSE file in - * the root directory of this source tree. - * - * @flow - */ - -import type {Task, TaskEvent} from '../../commons-node/tasks'; -import type {TaskMetadata} from '../../nuclide-task-runner/lib/types'; -import type {ArcToolbarModel as ArcToolbarModelType} from './ArcToolbarModel'; -import type {Message} from '../../nuclide-console/lib/types'; -import type {Directory} from '../../nuclide-remote-connection'; - -import UniversalDisposable from '../../commons-node/UniversalDisposable'; -import {taskFromObservable} from '../../commons-node/tasks'; -import {observableFromSubscribeFunction} from '../../commons-node/event'; -import {createExtraUiComponent} from './ui/createExtraUiComponent'; -import {React} from 'react-for-atom'; -import {Observable, Subject} from 'rxjs'; - -export default class ArcBuildSystem { - _model: ArcToolbarModelType; - _extraUi: ?ReactClass; - id: string; - name: string; - _outputMessages: Subject; - _disposables: UniversalDisposable; +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _UniversalDisposable; + +function _load_UniversalDisposable() { + return _UniversalDisposable = _interopRequireDefault(require('../../commons-node/UniversalDisposable')); +} + +var _tasks; + +function _load_tasks() { + return _tasks = require('../../commons-node/tasks'); +} + +var _event; + +function _load_event() { + return _event = require('../../commons-node/event'); +} + +var _createExtraUiComponent; + +function _load_createExtraUiComponent() { + return _createExtraUiComponent = require('./ui/createExtraUiComponent'); +} + +var _reactForAtom = require('react-for-atom'); + +var _rxjsBundlesRxMinJs = require('rxjs/bundles/Rx.min.js'); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +class ArcBuildSystem { constructor() { this.id = 'arcanist'; - this._outputMessages = new Subject(); + this._outputMessages = new _rxjsBundlesRxMinJs.Subject(); this._model = this._getModel(); this.name = this._model.getName(); - this._disposables = new UniversalDisposable(this._outputMessages); + this._disposables = new (_UniversalDisposable || _load_UniversalDisposable()).default(this._outputMessages); } - setProjectRoot( - projectRoot: ?Directory, - callback: (enabled: boolean, taskList: Array) => mixed, - ): IDisposable { + setProjectRoot(projectRoot, callback) { const path = projectRoot ? projectRoot.getPath() : null; this._model.setProjectPath(path); - const storeReady = observableFromSubscribeFunction(this._model.onChange.bind(this._model)) - .map(() => this._model) - .startWith(this._model) - .filter(model => model.isArcSupported() !== null && model.getActiveProjectPath() === path); + const storeReady = (0, (_event || _load_event()).observableFromSubscribeFunction)(this._model.onChange.bind(this._model)).map(() => this._model).startWith(this._model).filter(model => model.isArcSupported() !== null && model.getActiveProjectPath() === path); - const enabledObservable = storeReady - .map(model => model.isArcSupported() === true) - .distinctUntilChanged(); + const enabledObservable = storeReady.map(model => model.isArcSupported() === true).distinctUntilChanged(); const tasksObservable = storeReady.map(model => model.getTaskList()); - return new UniversalDisposable( - Observable.combineLatest(enabledObservable, tasksObservable) - .subscribe(([enabled, tasks]) => callback(enabled, tasks)), - ); + return new (_UniversalDisposable || _load_UniversalDisposable()).default(_rxjsBundlesRxMinJs.Observable.combineLatest(enabledObservable, tasksObservable).subscribe(([enabled, tasks]) => callback(enabled, tasks))); } - _getModel(): ArcToolbarModelType { + _getModel() { let ArcToolbarModel; try { // $FlowFB @@ -72,39 +68,46 @@ export default class ArcBuildSystem { return new ArcToolbarModel(this._outputMessages); } - getExtraUi(): ReactClass { + getExtraUi() { if (this._extraUi == null) { - this._extraUi = createExtraUiComponent(this._model); + this._extraUi = (0, (_createExtraUiComponent || _load_createExtraUiComponent()).createExtraUiComponent)(this._model); } return this._extraUi; } - getIcon(): ReactClass { + getIcon() { return ArcIcon; } - getOutputMessages(): Observable { + getOutputMessages() { return this._outputMessages; } - runTask(taskType: string): Task { + runTask(taskType) { if (!this._model.getTaskList().some(task => task.type === taskType)) { throw new Error(`There's no hhvm task named "${taskType}"`); } const taskFunction = getTaskRunFunction(this._model, taskType); - return taskFromObservable(taskFunction()); + return (0, (_tasks || _load_tasks()).taskFromObservable)(taskFunction()); } - dispose(): void { + dispose() { this._disposables.dispose(); } } -function getTaskRunFunction( - model: ArcToolbarModelType, - taskType: string, -): () => Observable { +exports.default = ArcBuildSystem; /** + * Copyright (c) 2015-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the license found in the LICENSE file in + * the root directory of this source tree. + * + * + */ + +function getTaskRunFunction(model, taskType) { switch (taskType) { case 'build': return () => model.arcBuild(); @@ -113,4 +116,9 @@ function getTaskRunFunction( } } -const ArcIcon = () => arc; +const ArcIcon = () => _reactForAtom.React.createElement( + 'span', + null, + 'arc' +); +module.exports = exports['default']; \ No newline at end of file diff --git a/pkg/nuclide-arcanist/lib/ArcToolbarModel.js b/pkg/nuclide-arcanist/lib/ArcToolbarModel.js index 305a41b8ac..cc46bc22c1 100644 --- a/pkg/nuclide-arcanist/lib/ArcToolbarModel.js +++ b/pkg/nuclide-arcanist/lib/ArcToolbarModel.js @@ -1,3 +1,22 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.ArcToolbarModel = exports.TASKS = undefined; + +var _asyncToGenerator = _interopRequireDefault(require('async-to-generator')); + +var _atom = require('atom'); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const TASKS = exports.TASKS = []; + +/* + * This will provide the toolbar functionality for the open-source-supported HHVM targets. + * e.g. HHVM Debugger + */ /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,87 +24,75 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * */ -import type {TaskEvent} from '../../commons-node/tasks'; -import type {TaskMetadata} from '../../nuclide-task-runner/lib/types'; -import type {Level, Message} from '../../nuclide-console/lib/types'; -import type {Observable, Subject} from 'rxjs'; - -import {Disposable} from 'atom'; - -export const TASKS: Array = []; +class ArcToolbarModel { -/* - * This will provide the toolbar functionality for the open-source-supported HHVM targets. - * e.g. HHVM Debugger - */ -export class ArcToolbarModel { - _projectPath: ?string - _outputMessages: Subject; - - constructor(outputMessages: Subject) { + constructor(outputMessages) { this._outputMessages = outputMessages; } - setProjectPath(projectPath: ?string) { + setProjectPath(projectPath) { this._projectPath = projectPath; } - logOutput(text: string, level: Level) { - this._outputMessages.next({text, level}); + logOutput(text, level) { + this._outputMessages.next({ text, level }); } - getActiveProjectPath(): ?string { + getActiveProjectPath() { return this._projectPath; } - onChange(callback: () => mixed): IDisposable { - return new Disposable(() => {}); + onChange(callback) { + return new _atom.Disposable(() => {}); } - setActiveBuildTarget(value: string): void { + setActiveBuildTarget(value) { throw new Error('arc build targets not supported'); } - isArcSupported(): ?boolean { + isArcSupported() { return false; } - getActiveBuildTarget(): string { + getActiveBuildTarget() { return ''; } - getName(): string { + getName() { return 'Arcanist'; } - getTaskList(): Array { + getTaskList() { return TASKS; } - async arcBuild(): Observable { - throw new Error('arc build not supported'); + arcBuild() { + return (0, _asyncToGenerator.default)(function* () { + throw new Error('arc build not supported'); + })(); } - getBuildTargets(): ?Array { + getBuildTargets() { throw new Error('arc build not supported'); } - updateBuildTargets(): void { + updateBuildTargets() { throw new Error('arc build not supported'); } - getBuildTargetsError(): ?Error { + getBuildTargetsError() { throw new Error('arc build not supported'); } - viewActivated(): void { + viewActivated() { throw new Error('arc build not supported'); } - viewDeactivated(): void { + viewDeactivated() { throw new Error('arc build not supported'); } } +exports.ArcToolbarModel = ArcToolbarModel; \ No newline at end of file diff --git a/pkg/nuclide-arcanist/lib/ArcToolbarSection.js b/pkg/nuclide-arcanist/lib/ArcToolbarSection.js index 357efe3ebd..d483547379 100644 --- a/pkg/nuclide-arcanist/lib/ArcToolbarSection.js +++ b/pkg/nuclide-arcanist/lib/ArcToolbarSection.js @@ -1,3 +1,35 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _reactForAtom = require('react-for-atom'); + +var _ArcToolbarModel; + +function _load_ArcToolbarModel() { + return _ArcToolbarModel = require('./ArcToolbarModel'); +} + +var _Button; + +function _load_Button() { + return _Button = require('../../nuclide-ui/Button'); +} + +var _ButtonGroup; + +function _load_ButtonGroup() { + return _ButtonGroup = require('../../nuclide-ui/ButtonGroup'); +} + +var _Dropdown; + +function _load_Dropdown() { + return _Dropdown = require('../../nuclide-ui/Dropdown'); +} + /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. @@ -5,97 +37,91 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. * - * @flow + * */ -import type {Option} from '../../nuclide-ui/Dropdown'; - -import {React} from 'react-for-atom'; -import {ArcToolbarModel} from './ArcToolbarModel'; -import {Button, ButtonSizes} from '../../nuclide-ui/Button'; -import {ButtonGroup} from '../../nuclide-ui/ButtonGroup'; -import {Dropdown} from '../../nuclide-ui/Dropdown'; -import invariant from 'assert'; +class ArcToolbarSection extends _reactForAtom.React.Component { -type Props = { - model: ArcToolbarModel, -}; - -export default class ArcToolbarSection extends React.Component { - props: Props; - - constructor(props: Props) { + constructor(props) { super(props); - (this: any)._arcBuild = this._arcBuild.bind(this); - (this: any)._handleBuildTargetChange = this._handleBuildTargetChange.bind(this); - (this: any)._reloadBuildTargets = this._reloadBuildTargets.bind(this); + this._arcBuild = this._arcBuild.bind(this); + this._handleBuildTargetChange = this._handleBuildTargetChange.bind(this); + this._reloadBuildTargets = this._reloadBuildTargets.bind(this); } - componentDidMount(): void { + componentDidMount() { this.props.model.viewActivated(); } - componentWillUnmount(): void { + componentWillUnmount() { this.props.model.viewDeactivated(); } - getOptions(): Array